Add --output-to-tab flag for :spawn.

This puts the exit status, stdout, and stderr in a new tab.
This commit is contained in:
George Edward Bulmer 2017-12-08 16:44:53 +00:00
parent d4cadcc62e
commit 9f9311840a
4 changed files with 44 additions and 6 deletions

View File

@ -1148,7 +1148,7 @@ Set a mark at the current scroll position in the current tab.
[[spawn]]
=== spawn
Syntax: +:spawn [*--userscript*] [*--verbose*] [*--detach*] 'cmdline'+
Syntax: +:spawn [*--userscript*] [*--verbose*] [*--output-to-tab*] [*--detach*] 'cmdline'+
Spawn a command in a shell.
@ -1163,6 +1163,7 @@ Spawn a command in a shell.
- `/usr/share/qutebrowser/userscripts`
* +*-v*+, +*--verbose*+: Show notifications when the command started/exited.
* +*-v*+, +*--output-to-tab*+: Show stderr, stdout, and exit status in a new tab.
* +*-d*+, +*--detach*+: Whether the command should be detached from qutebrowser.
==== note

View File

@ -1177,7 +1177,8 @@ class CommandDispatcher:
@cmdutils.register(instance='command-dispatcher', scope='window',
maxsplit=0, no_replace_variables=True)
def spawn(self, cmdline, userscript=False, verbose=False, detach=False):
def spawn(self, cmdline, userscript=False, verbose=False,
output_to_tab=False, detach=False):
"""Spawn a command in a shell.
Args:
@ -1208,7 +1209,8 @@ class CommandDispatcher:
else:
cmd = os.path.expanduser(cmd)
proc = guiprocess.GUIProcess(what='command', verbose=verbose,
parent=self._tabbed_browser)
parent=self._tabbed_browser,
output_to_tab=output_to_tab)
if detach:
proc.start_detached(cmd, args)
else:

View File

@ -42,6 +42,7 @@ from qutebrowser.misc import objects
pyeval_output = ":pyeval was never called"
spawn_output = ":spawn was never called"
_HANDLERS = {}
@ -268,6 +269,13 @@ def qute_pyeval(_url):
return 'text/html', html
@add_handler('spawn_output')
def qute_spawn_output(_url):
"""Handler for qute://spawn_output."""
html = jinja.render('pre.html', title='spawn output', content=spawn_output)
return 'text/html', html
@add_handler('version')
@add_handler('verizon')
def qute_version(_url):

View File

@ -22,9 +22,11 @@
import shlex
from PyQt5.QtCore import (pyqtSlot, pyqtSignal, QObject, QProcess,
QProcessEnvironment)
QProcessEnvironment, QUrl)
from qutebrowser.utils import message, log
from qutebrowser.utils import message, log, objreg
from qutebrowser.browser import qutescheme
# A mapping of QProcess::ErrorCode's to human-readable strings.
@ -62,10 +64,11 @@ class GUIProcess(QObject):
started = pyqtSignal()
def __init__(self, what, *, verbose=False, additional_env=None,
parent=None):
parent=None, output_to_tab=False):
super().__init__(parent)
self._what = what
self.verbose = verbose
self.output_to_tab = output_to_tab
self._started = False
self.cmd = None
self.args = None
@ -96,6 +99,30 @@ class GUIProcess(QObject):
self._started = False
log.procs.debug("Process finished with code {}, status {}.".format(
code, status))
stdout = None
stderr = None
if self.output_to_tab:
stderr = bytes(self._proc.readAllStandardError()).decode('utf-8')
stdout = bytes(self._proc.readAllStandardOutput()).decode('utf-8')
spawn_log = ""
spawn_log += "Process finished with code {},status {}.".format(
code, status)
if stdout:
spawn_log += "\nProcess stdout:\n" + stdout.strip()
if stderr:
spawn_log += "\nProcess stderr:\n" + stderr.strip()
qutescheme.spawn_output = spawn_log
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window='last-focused')
tabbed_browser.openurl(QUrl('qute://spawn_output'), newtab=True)
if status == QProcess.CrashExit:
message.error("{} crashed!".format(self._what.capitalize()))
elif status == QProcess.NormalExit and code == 0: