diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index af3fd459b..5dffe1733 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -11,6 +11,7 @@ |<>|Whether to find text on a page case-insensitively. |<>|The default page(s) to open at the start, separated by commas. |<>|The URL parameters to strip with :yank url, separated by commas. +|<>|The default program used to open downloads. Set to an empty string to use the default internal handler. |<>|The page to open if :open -t/-b/-w is used without URL. Use `about:blank` for a blank page. |<>|Whether to start a search when something else than a URL is entered. |<>|Whether to save the config automatically on quit. @@ -331,6 +332,14 @@ The URL parameters to strip with :yank url, separated by commas. Default: +pass:[ref,utm_source,utm_medium,utm_campaign,utm_term,utm_content]+ +[[general-default-open-dispatcher]] +=== default-open-dispatcher +The default program used to open downloads. Set to an empty string to use the default internal handler. + +Any {} in the string will be expanded to the filename, else the filename will be appended. + +Default: empty + [[general-default-page]] === default-page The page to open if :open -t/-b/-w is used without URL. Use `about:blank` for a blank page. diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index 12e766ecb..6326e6279 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -512,8 +512,8 @@ class AbstractDownloadItem(QObject): Args: cmdline: The command to use as string. A `{}` is expanded to the filename. None means to use the system's default - application. If no `{}` is found, the filename is appended - to the cmdline. + application or `default-open-dispatcher` if set. If no + `{}` is found, the filename is appended to the cmdline. """ assert self.successful filename = self._get_open_filename() @@ -521,13 +521,22 @@ class AbstractDownloadItem(QObject): log.downloads.error("No filename to open the download!") return - if cmdline is None: + # the default program to open downloads with - will be empty string + # if we want to use the default + override = config.get('general', 'default-open-dispatcher') + + # precedence order: cmdline > default-open-dispatcher > openUrl + + if cmdline is None and not override: log.downloads.debug("Opening {} with the system application" .format(filename)) url = QUrl.fromLocalFile(filename) QDesktopServices.openUrl(url) return + if cmdline is None and override: + cmdline = override + cmd, *args = shlex.split(cmdline) args = [arg.replace('{}', filename) for arg in args] if '{}' not in cmdline: diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 3a1b71e01..3b71c6044 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -147,6 +147,13 @@ def data(readonly=False): "The URL parameters to strip with :yank url, separated by " "commas."), + ('default-open-dispatcher', + SettingValue(typ.String(none_ok=True), ''), + "The default program used to open downloads. Set to an empty " + "string to use the default internal handler.\n\n" + "Any {} in the string will be expanded to the filename, else " + "the filename will be appended."), + ('default-page', SettingValue(typ.FuzzyUrl(), '${startpage}'), "The page to open if :open -t/-b/-w is used without URL. Use " diff --git a/tests/end2end/features/downloads.feature b/tests/end2end/features/downloads.feature index b6a38da29..5b4c4f9a4 100644 --- a/tests/end2end/features/downloads.feature +++ b/tests/end2end/features/downloads.feature @@ -337,6 +337,20 @@ Feature: Downloading things from a website. And I open the download with a placeholder Then "Opening *download.bin* with [*python*]" should be logged + Scenario: Opening a download with default-open-dispatcher set + When I set a test python default-open-dispatcher + And I open data/downloads/download.bin without waiting + And I wait until the download is finished + And I run :download-open + Then "Opening *download.bin* with [*python*]" should be logged + + Scenario: Opening a download with default-open-dispatcher set and override + When I set general -> default-open-dispatcher to cat + And I open data/downloads/download.bin without waiting + And I wait until the download is finished + And I open the download + Then "Opening *download.bin* with [*python*]" should be logged + Scenario: Opening a download which does not exist When I run :download-open with count 42 Then the error "There's no download 42!" should be shown diff --git a/tests/end2end/features/test_downloads_bdd.py b/tests/end2end/features/test_downloads_bdd.py index 65ccf1f3e..753cfa75c 100644 --- a/tests/end2end/features/test_downloads_bdd.py +++ b/tests/end2end/features/test_downloads_bdd.py @@ -101,6 +101,13 @@ def download_prompt(tmpdir, quteproc, path): quteproc.send_cmd(':leave-mode') +@bdd.when("I set a test python default-open-dispatcher") +def default_open_dispatcher_python(quteproc, tmpdir): + cmd = '{} -c "import sys; print(sys.argv[1])"'.format( + shlex.quote(sys.executable)) + quteproc.set_setting('general', 'default-open-dispatcher', cmd) + + @bdd.when("I open the download") def download_open(quteproc): cmd = '{} -c "import sys; print(sys.argv[1])"'.format(