Add {clipboard} and {primary} to replace :paste

:paste is deprecated and replaced by equivalents using :open and the
new variables, and :open supports opening newline-separated lists of
URLs.
This commit is contained in:
Jan Verbeek 2016-08-06 22:03:50 +02:00
parent 778ccad39f
commit 0177dafbd0
6 changed files with 93 additions and 69 deletions

View File

@ -34,7 +34,6 @@
|<<messages,messages>>|Show a log of past messages. |<<messages,messages>>|Show a log of past messages.
|<<navigate,navigate>>|Open typical prev/next links or navigate using the URL path. |<<navigate,navigate>>|Open typical prev/next links or navigate using the URL path.
|<<open,open>>|Open a URL in the current/[count]th tab. |<<open,open>>|Open a URL in the current/[count]th tab.
|<<paste,paste>>|Open a page from the clipboard.
|<<print,print>>|Print the current/[count]th tab. |<<print,print>>|Print the current/[count]th tab.
|<<quickmark-add,quickmark-add>>|Add a new quickmark. |<<quickmark-add,quickmark-add>>|Add a new quickmark.
|<<quickmark-del,quickmark-del>>|Delete a quickmark. |<<quickmark-del,quickmark-del>>|Delete a quickmark.
@ -473,6 +472,8 @@ Syntax: +:open [*--implicit*] [*--bg*] [*--tab*] [*--window*] ['url']+
Open a URL in the current/[count]th tab. Open a URL in the current/[count]th tab.
If the URL contains newlines, each line gets opened in its own tab.
==== positional arguments ==== positional arguments
* +'url'+: The URL to open. * +'url'+: The URL to open.
@ -489,20 +490,6 @@ The tab index to open the URL in.
==== note ==== note
* This command does not split arguments after the last argument and handles quotes literally. * This command does not split arguments after the last argument and handles quotes literally.
[[paste]]
=== paste
Syntax: +:paste [*--sel*] [*--tab*] [*--bg*] [*--window*]+
Open a page from the clipboard.
If the pasted text contains newlines, each line gets opened in its own tab.
==== optional arguments
* +*-s*+, +*--sel*+: Use the primary selection instead of the clipboard.
* +*-t*+, +*--tab*+: Open in a new tab.
* +*-b*+, +*--bg*+: Open in a background tab.
* +*-w*+, +*--window*+: Open in new window.
[[print]] [[print]]
=== print === print
Syntax: +:print [*--preview*] [*--pdf* 'file']+ Syntax: +:print [*--preview*] [*--pdf* 'file']+

View File

@ -236,6 +236,8 @@ class CommandDispatcher:
bg=False, tab=False, window=False, count=None): bg=False, tab=False, window=False, count=None):
"""Open a URL in the current/[count]th tab. """Open a URL in the current/[count]th tab.
If the URL contains newlines, each line gets opened in its own tab.
Args: Args:
url: The URL to open. url: The URL to open.
bg: Open in a new background tab. bg: Open in a new background tab.
@ -245,37 +247,60 @@ class CommandDispatcher:
clicking on a link). clicking on a link).
count: The tab index to open the URL in, or None. count: The tab index to open the URL in, or None.
""" """
force_search = False
if url is None: if url is None:
if tab or bg or window: if tab or bg or window:
url = config.get('general', 'default-page') urls = [config.get('general', 'default-page')]
else: else:
raise cmdexc.CommandError("No URL given, but -t/-b/-w is not " raise cmdexc.CommandError("No URL given, but -t/-b/-w is not "
"set!") "set!")
else: else:
try: urllist = [u for u in url.split('\n') if u.strip()]
url = objreg.get('quickmark-manager').get(url) if (len(urllist) > 1 and
except urlmarks.Error: any(not urlutils.is_url(u) and
try: urlutils.get_path_if_valid(u, check_exists=True)
url = urlutils.fuzzy_url(url) is None for u in urllist)):
except urlutils.InvalidUrlError as e: urllist = [url]
# We don't use cmdexc.CommandError here as this can be force_search = True
# called async from edit_url urls = [x for x in [self._parse_url(u, force_search=force_search)
message.error(self._win_id, str(e)) for u in urllist] if x is not None]
return for i, cur_url in enumerate(urls):
if tab or bg or window: if not window and i > 0:
self._open(url, tab, bg, window, not implicit) tab = False
else: bg = True
curtab = self._cntwidget(count) if tab or bg or window:
if curtab is None: self._open(cur_url, tab, bg, window, not implicit)
if count is None:
# We want to open a URL in the current tab, but none exists
# yet.
self._tabbed_browser.tabopen(url)
else:
# Explicit count with a tab that doesn't exist.
return
else: else:
curtab.openurl(url) curtab = self._cntwidget(count)
if curtab is None:
if count is None:
# We want to open a URL in the current tab, but none
# exists yet.
self._tabbed_browser.tabopen(cur_url)
else:
curtab.openurl(cur_url)
def _parse_url(self, url, force_search=False):
"""Parse a URL or quickmark or search query.
Args:
url: The URL to parse.
force_search: Whether to force a search even if the content can be
interpreted as a URL or a path.
Return:
A URL that can be opened."""
try:
return objreg.get('quickmark-manager').get(url)
except urlmarks.Error:
try:
return urlutils.fuzzy_url(url, force_search=force_search)
except urlutils.InvalidUrlError as e:
# We don't use cmdexc.CommandError here as this can be
# called async from edit_url
message.error(self._win_id, str(e))
return
@cmdutils.register(instance='command-dispatcher', name='reload', @cmdutils.register(instance='command-dispatcher', name='reload',
scope='window') scope='window')
@ -776,7 +801,8 @@ class CommandDispatcher:
else: else:
raise cmdexc.CommandError("Last tab") raise cmdexc.CommandError("Last tab")
@cmdutils.register(instance='command-dispatcher', scope='window') @cmdutils.register(instance='command-dispatcher', scope='window',
deprecated="Use :open {clipboard}")
def paste(self, sel=False, tab=False, bg=False, window=False): def paste(self, sel=False, tab=False, bg=False, window=False):
"""Open a page from the clipboard. """Open a page from the clipboard.
@ -796,9 +822,6 @@ class CommandDispatcher:
sel = False sel = False
target = "Clipboard" target = "Clipboard"
text = utils.get_clipboard(selection=sel) text = utils.get_clipboard(selection=sel)
if not text.strip():
raise cmdexc.CommandError("{} is empty.".format(target))
log.misc.debug("{} contained: {!r}".format(target, text))
text_urls = [u for u in text.split('\n') if u.strip()] text_urls = [u for u in text.split('\n') if u.strip()]
if (len(text_urls) > 1 and not urlutils.is_url(text_urls[0]) and if (len(text_urls) > 1 and not urlutils.is_url(text_urls[0]) and
urlutils.get_path_if_valid( urlutils.get_path_if_valid(

View File

@ -26,7 +26,7 @@ from PyQt5.QtCore import pyqtSlot, QUrl, QObject
from qutebrowser.config import config, configexc from qutebrowser.config import config, configexc
from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.commands import cmdexc, cmdutils
from qutebrowser.utils import message, objreg, qtutils from qutebrowser.utils import message, objreg, qtutils, utils
from qutebrowser.misc import split from qutebrowser.misc import split
@ -57,11 +57,19 @@ def replace_variables(win_id, arglist):
QUrl.RemovePassword) QUrl.RemovePassword)
if '{url:pretty}' in arglist: if '{url:pretty}' in arglist:
pretty_url = _current_url(tabbed_browser).toString(QUrl.RemovePassword) pretty_url = _current_url(tabbed_browser).toString(QUrl.RemovePassword)
if '{clipboard}' in arglist:
clipboard = utils.get_clipboard()
if '{primary}' in arglist:
primary = utils.get_clipboard(selection=True)
for arg in arglist: for arg in arglist:
if arg == '{url}': if arg == '{url}':
args.append(url) args.append(url)
elif arg == '{url:pretty}': elif arg == '{url:pretty}':
args.append(pretty_url) args.append(pretty_url)
elif arg == '{clipboard}':
args.append(clipboard)
elif arg == '{primary}':
args.append(primary)
else: else:
args.append(arg) args.append(arg)
return args return args

View File

@ -1512,12 +1512,12 @@ KEY_DATA = collections.OrderedDict([
('yank -ds', ['yD']), ('yank -ds', ['yD']),
('yank -p', ['yp']), ('yank -p', ['yp']),
('yank -ps', ['yP']), ('yank -ps', ['yP']),
('paste', ['pp']), ('open {clipboard}', ['pp']),
('paste -s', ['pP']), ('open {primary}', ['pP']),
('paste -t', ['Pp']), ('open -t {clipboard}', ['Pp']),
('paste -ts', ['PP']), ('open -t {primary}', ['PP']),
('paste -w', ['wp']), ('open -w {clipboard}', ['wp']),
('paste -ws', ['wP']), ('open -w {primary}', ['wP']),
('quickmark-save', ['m']), ('quickmark-save', ['m']),
('set-cmd-text -s :quickmark-load', ['b']), ('set-cmd-text -s :quickmark-load', ['b']),
('set-cmd-text -s :quickmark-load -t', ['B']), ('set-cmd-text -s :quickmark-load -t', ['B']),

View File

@ -37,6 +37,7 @@ import pkg_resources
import qutebrowser import qutebrowser
from qutebrowser.utils import qtutils, log from qutebrowser.utils import qtutils, log
from qutebrowser.commands import cmdexc
fake_clipboard = None fake_clipboard = None
@ -810,6 +811,11 @@ def get_clipboard(selection=False):
mode = QClipboard.Selection if selection else QClipboard.Clipboard mode = QClipboard.Selection if selection else QClipboard.Clipboard
data = QApplication.clipboard().text(mode=mode) data = QApplication.clipboard().text(mode=mode)
target = "Primary selection" if selection else "Clipboard"
if not data.strip():
raise cmdexc.CommandError("{} is empty.".format(target))
log.misc.debug("{} contained: {!r}".format(target, data))
return data return data

View File

@ -1,6 +1,6 @@
Feature: Yanking and pasting. Feature: Yanking and pasting.
:yank and :paste can be used to copy/paste the URL or title from/to the :yank, {clipboard} and {primary} can be used to copy/paste the URL or title
clipboard and primary selection. from/to the clipboard and primary selection.
Background: Background:
Given I run :tab-only Given I run :tab-only
@ -45,11 +45,11 @@ Feature: Yanking and pasting.
Then the message "Yanked URL to clipboard: http://localhost:(port)/data/title with spaces.html" should be shown 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" And the clipboard should contain "http://localhost:(port)/data/title with spaces.html"
#### :paste #### {clipboard} and {primary}
Scenario: Pasting a URL Scenario: Pasting a URL
When I put "http://localhost:(port)/data/hello.txt" into the clipboard When I put "http://localhost:(port)/data/hello.txt" into the clipboard
And I run :paste And I run :open {clipboard}
And I wait until data/hello.txt is loaded And I wait until data/hello.txt is loaded
Then the requests should be: Then the requests should be:
data/hello.txt data/hello.txt
@ -57,32 +57,32 @@ Feature: Yanking and pasting.
Scenario: Pasting a URL from primary selection Scenario: Pasting a URL from primary selection
When selection is supported When selection is supported
And I put "http://localhost:(port)/data/hello2.txt" into the primary selection And I put "http://localhost:(port)/data/hello2.txt" into the primary selection
And I run :paste --sel And I run :open {primary}
And I wait until data/hello2.txt is loaded And I wait until data/hello2.txt is loaded
Then the requests should be: Then the requests should be:
data/hello2.txt data/hello2.txt
Scenario: Pasting with empty clipboard Scenario: Pasting with empty clipboard
When I put "" into the clipboard When I put "" into the clipboard
And I run :paste And I run :open {clipboard} (invalid command)
Then the error "Clipboard is empty." should be shown Then the error "Clipboard is empty." should be shown
Scenario: Pasting with empty selection Scenario: Pasting with empty selection
When selection is supported When selection is supported
And I put "" into the primary selection And I put "" into the primary selection
And I run :paste --sel And I run :open {primary} (invalid command)
Then the error "Primary selection is empty." should be shown Then the error "Primary selection is empty." should be shown
Scenario: Pasting with a space in clipboard Scenario: Pasting with a space in clipboard
When I put " " into the clipboard When I put " " into the clipboard
And I run :paste And I run :open {clipboard} (invalid command)
Then the error "Clipboard is empty." should be shown Then the error "Clipboard is empty." should be shown
Scenario: Pasting in a new tab Scenario: Pasting in a new tab
Given I open about:blank Given I open about:blank
When I run :tab-only When I run :tab-only
And I put "http://localhost:(port)/data/hello.txt" into the clipboard And I put "http://localhost:(port)/data/hello.txt" into the clipboard
And I run :paste -t And I run :open -t {clipboard}
And I wait until data/hello.txt is loaded And I wait until data/hello.txt is loaded
Then the following tabs should be open: Then the following tabs should be open:
- about:blank - about:blank
@ -92,7 +92,7 @@ Feature: Yanking and pasting.
Given I open about:blank Given I open about:blank
When I run :tab-only When I run :tab-only
And I put "http://localhost:(port)/data/hello.txt" into the clipboard And I put "http://localhost:(port)/data/hello.txt" into the clipboard
And I run :paste -b And I run :open -b {clipboard}
And I wait until data/hello.txt is loaded And I wait until data/hello.txt is loaded
Then the following tabs should be open: Then the following tabs should be open:
- about:blank (active) - about:blank (active)
@ -101,7 +101,7 @@ Feature: Yanking and pasting.
Scenario: Pasting in a new window Scenario: Pasting in a new window
Given I have a fresh instance Given I have a fresh instance
When I put "http://localhost:(port)/data/hello.txt" into the clipboard When I put "http://localhost:(port)/data/hello.txt" into the clipboard
And I run :paste -w And I run :open -w {clipboard}
And I wait until data/hello.txt is loaded And I wait until data/hello.txt is loaded
Then the session should look like: Then the session should look like:
windows: windows:
@ -119,7 +119,7 @@ Feature: Yanking and pasting.
Scenario: Pasting an invalid URL Scenario: Pasting an invalid URL
When I set general -> auto-search to false When I set general -> auto-search to false
And I put "foo bar" into the clipboard And I put "foo bar" into the clipboard
And I run :paste And I run :open {clipboard}
Then the error "Invalid URL" should be shown Then the error "Invalid URL" should be shown
Scenario: Pasting multiple urls in a new tab Scenario: Pasting multiple urls in a new tab
@ -128,7 +128,7 @@ Feature: Yanking and pasting.
http://localhost:(port)/data/hello.txt http://localhost:(port)/data/hello.txt
http://localhost:(port)/data/hello2.txt http://localhost:(port)/data/hello2.txt
http://localhost:(port)/data/hello3.txt http://localhost:(port)/data/hello3.txt
And I run :paste -t And I run :open -t {clipboard}
And I wait until data/hello.txt is loaded And I wait until data/hello.txt is loaded
And I wait until data/hello2.txt is loaded And I wait until data/hello2.txt is loaded
And I wait until data/hello3.txt is loaded And I wait until data/hello3.txt is loaded
@ -145,7 +145,7 @@ Feature: Yanking and pasting.
this url: this url:
http://qutebrowser.org http://qutebrowser.org
should not open should not open
And I run :paste -t And I run :open -t {clipboard}
And I wait until data/hello.txt?q=this%20url%3A%0Ahttp%3A//qutebrowser.org%0Ashould%20not%20open is loaded And I wait until data/hello.txt?q=this%20url%3A%0Ahttp%3A//qutebrowser.org%0Ashould%20not%20open is loaded
Then the following tabs should be open: Then the following tabs should be open:
- about:blank - about:blank
@ -159,7 +159,7 @@ Feature: Yanking and pasting.
text: text:
should open should open
as search as search
And I run :paste -t And I run :open -t {clipboard}
And I wait until data/hello.txt?q=text%3A%0Ashould%20open%0Aas%20search is loaded And I wait until data/hello.txt?q=text%3A%0Ashould%20open%0Aas%20search is loaded
Then the following tabs should be open: Then the following tabs should be open:
- about:blank - about:blank
@ -172,7 +172,7 @@ Feature: Yanking and pasting.
http://localhost:(port)/data/hello.txt http://localhost:(port)/data/hello.txt
http://localhost:(port)/data/hello2.txt http://localhost:(port)/data/hello2.txt
http://localhost:(port)/data/hello3.txt http://localhost:(port)/data/hello3.txt
And I run :paste -b And I run :open -b {clipboard}
And I wait until data/hello.txt is loaded And I wait until data/hello.txt is loaded
And I wait until data/hello2.txt is loaded And I wait until data/hello2.txt is loaded
And I wait until data/hello3.txt is loaded And I wait until data/hello3.txt is loaded
@ -188,7 +188,7 @@ Feature: Yanking and pasting.
http://localhost:(port)/data/hello.txt http://localhost:(port)/data/hello.txt
http://localhost:(port)/data/hello2.txt http://localhost:(port)/data/hello2.txt
http://localhost:(port)/data/hello3.txt http://localhost:(port)/data/hello3.txt
And I run :paste -w And I run :open -w {clipboard}
And I wait until data/hello.txt is loaded And I wait until data/hello.txt is loaded
And I wait until data/hello2.txt is loaded And I wait until data/hello2.txt is loaded
And I wait until data/hello3.txt is loaded And I wait until data/hello3.txt is loaded
@ -218,13 +218,13 @@ Feature: Yanking and pasting.
Scenario: Pasting multiple urls with an empty one Scenario: Pasting multiple urls with an empty one
When I open about:blank When I open about:blank
And I put "http://localhost:(port)/data/hello.txt\n\nhttp://localhost:(port)/data/hello2.txt" into the clipboard And I put "http://localhost:(port)/data/hello.txt\n\nhttp://localhost:(port)/data/hello2.txt" into the clipboard
And I run :paste -t And I run :open -t {clipboard}
Then no crash should happen Then no crash should happen
Scenario: Pasting multiple urls with an almost empty one Scenario: Pasting multiple urls with an almost empty one
When I open about:blank When I open about:blank
And I put "http://localhost:(port)/data/hello.txt\n \nhttp://localhost:(port)/data/hello2.txt" into the clipboard And I put "http://localhost:(port)/data/hello.txt\n \nhttp://localhost:(port)/data/hello2.txt" into the clipboard
And I run :paste -t And I run :open -t {clipboard}
Then no crash should happen Then no crash should happen
#### :paste-primary #### :paste-primary