diff --git a/qutebrowser/app.py b/qutebrowser/app.py index f00d71a78..8b7e6b927 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -57,6 +57,9 @@ from qutebrowser.utils.appdirs import AppDirs from qutebrowser.utils.misc import set_trace +components = {} + + class QuteBrowser(QApplication): """Main object for qutebrowser. @@ -130,6 +133,8 @@ class QuteBrowser(QApplication): self.keyparser.keystring_updated.connect( self.mainwindow.status.keystring.setText) + components['app'] = self + self.mainwindow.show() self._python_hacks() timer = QTimer.singleShot(0, self._process_init_args) @@ -322,7 +327,7 @@ class QuteBrowser(QApplication): logging.debug("maybe_quit quitting.") self.quit() - @cmdutils.register(split_args=False) + @cmdutils.register(instance='app', split_args=False) def pyeval(self, s): """Evaluate a python string and display the results as a webpage. @@ -340,7 +345,7 @@ class QuteBrowser(QApplication): qutescheme.pyeval_output = out self.mainwindow.tabs.cur.openurl('qute:pyeval') - @cmdutils.register(hide=True) + @cmdutils.register(instance='app', hide=True) def crash(self): """Crash for debugging purposes. @@ -353,7 +358,7 @@ class QuteBrowser(QApplication): raise Exception("Forced crash") @pyqtSlot() - @cmdutils.register(name=['q', 'quit'], nargs=0) + @cmdutils.register(instance='app', name=['q', 'quit'], nargs=0) def shutdown(self, do_quit=True): """Try to shutdown everything cleanly. diff --git a/qutebrowser/commands/utils.py b/qutebrowser/commands/utils.py index 6d01d39a8..afde5bc1e 100644 --- a/qutebrowser/commands/utils.py +++ b/qutebrowser/commands/utils.py @@ -19,11 +19,14 @@ import shlex import inspect +import functools from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject +from PyQt5.QtWidgets import QApplication from PyQt5.QtWebKitWidgets import QWebPage import qutebrowser.config.config as config +from qutebrowser.app import components as qtb_components from qutebrowser.commands.template import Command from qutebrowser.commands.exceptions import (ArgumentCountError, NoSuchCommandError) @@ -40,11 +43,13 @@ class register: """ - def __init__(self, name=None, nargs=None, split_args=True, hide=False): + def __init__(self, instance=None, name=None, nargs=None, split_args=True, + hide=False): self.name = name self.split_args = split_args self.hide = hide self.nargs = nargs + self.instance = instance def __call__(self, func): global cmd_dict @@ -58,8 +63,12 @@ class register: names += name count, nargs = self._get_nargs_count(func) desc = func.__doc__.splitlines()[0].strip().rstrip('.') + if self.instance is not None: + handler = functools.partial(func, qtb_components[self.instance]) + else: + handler = func cmd = Command(mainname, self.split_args, self.hide, nargs, count, desc, - handler=func) + handler=handler) for name in names: cmd_dict[name] = cmd return func @@ -130,6 +139,7 @@ class SearchParser(QObject): self._text = None self._flags = 0 super().__init__(parent) + qtb_components['searchparser'] = self def _search(self, text, rev=False): """Search for a text on the current page. @@ -174,7 +184,7 @@ class SearchParser(QObject): """ self._search(text, rev=True) - @register(hide=True) + @register(instance='searchparser', hide=True) def nextsearch(self, count=1): """Continue the search to the ([count]th) next term. diff --git a/qutebrowser/widgets/browser.py b/qutebrowser/widgets/browser.py index 2128c4e97..af14d2bae 100644 --- a/qutebrowser/widgets/browser.py +++ b/qutebrowser/widgets/browser.py @@ -37,6 +37,7 @@ from PyQt5.QtWebKitWidgets import QWebView, QWebPage import qutebrowser.utils.url as urlutils import qutebrowser.config.config as config import qutebrowser.commands.utils as cmdutils +from qutebrowser.app import components as qtb_components from qutebrowser.widgets.tabbar import TabWidget from qutebrowser.network.networkmanager import NetworkManager from qutebrowser.utils.signals import SignalCache, dbg_signal @@ -114,6 +115,7 @@ class TabbedBrowser(TabWidget): self._space.activated.connect(lambda: self.cur.scroll_page(0, 1)) self.cur = CurCommandDispatcher(self) self.cur.temp_message.connect(self.cur_temp_message) + qtb_components['browser'] = self def _cb_tab_shutdown(self, tab): """Called after a tab has been shut down completely. @@ -247,7 +249,7 @@ class TabbedBrowser(TabWidget): tab.shutdown(callback=functools.partial(self._cb_tab_shutdown, tab)) - @cmdutils.register() + @cmdutils.register(instance='browser') def tabclose(self, count=None): """Close the current/[count]th tab. @@ -277,7 +279,7 @@ class TabbedBrowser(TabWidget): elif last_close == 'blank': tab.openurl('about:blank') - @cmdutils.register(split_args=False) + @cmdutils.register(instance='browser', split_args=False) def tabopen(self, url): """Open a new tab with a given url. @@ -311,7 +313,7 @@ class TabbedBrowser(TabWidget): tab.open_tab.connect(self.tabopen) tab.openurl(url) - @cmdutils.register(hide=True) + @cmdutils.register(instance='browser', hide=True) def tabopencur(self): """Set the statusbar to :tabopen and the current URL. @@ -322,7 +324,7 @@ class TabbedBrowser(TabWidget): url = urlutils.urlstring(self.currentWidget().url()) self.set_cmd_text.emit(':tabopen ' + url) - @cmdutils.register(hide=True) + @cmdutils.register(instance='browser', hide=True) def opencur(self): """Set the statusbar to :open and the current URL. @@ -333,7 +335,7 @@ class TabbedBrowser(TabWidget): url = urlutils.urlstring(self.currentWidget().url()) self.set_cmd_text.emit(':open ' + url) - @cmdutils.register(name='undo') + @cmdutils.register(instance='browser', name='undo') def undo_close(self): """Switch to the previous tab, or skip [count] tabs. @@ -343,7 +345,7 @@ class TabbedBrowser(TabWidget): if self._url_stack: self.tabopen(self._url_stack.pop()) - @cmdutils.register(name='tabprev') + @cmdutils.register(instance='browser', name='tabprev') def switch_prev(self, count=1): """Switch to the ([count]th) previous tab. @@ -360,7 +362,7 @@ class TabbedBrowser(TabWidget): # FIXME pass - @cmdutils.register('tabnext') + @cmdutils.register(instance='browser', name='tabnext') def switch_next(self, count=1): """Switch to the next tab, or skip [count] tabs. @@ -377,7 +379,7 @@ class TabbedBrowser(TabWidget): # FIXME pass - @cmdutils.register() + @cmdutils.register(instance='browser') def paste(self, sel=False): """Open a page from the clipboard. @@ -394,7 +396,7 @@ class TabbedBrowser(TabWidget): logging.debug("Clipboard contained: '{}'".format(url)) self.openurl(url) - @cmdutils.register() + @cmdutils.register(instance='browser') def tabpaste(self, sel=False): """Open a page from the clipboard in a new tab. @@ -489,7 +491,7 @@ class CurCommandDispatcher(QObject): return frame.setScrollBarValue(orientation, int(m * perc / 100)) - @cmdutils.register(name='open', split_args=False) + @cmdutils.register(instance='browser', name='open', split_args=False) def openurl(self, url, count=None): """Open an url in the current/[count]th tab. @@ -512,7 +514,7 @@ class CurCommandDispatcher(QObject): else: tab.openurl(url) - @cmdutils.register(name='reload') + @cmdutils.register(instance='browser', name='reload') def reloadpage(self, count=None): """Reload the current/[count]th tab. @@ -526,7 +528,7 @@ class CurCommandDispatcher(QObject): if tab is not None: tab.reload() - @cmdutils.register() + @cmdutils.register(instance='browser') def stop(self, count=None): """Stop loading in the current/[count]th tab. @@ -540,7 +542,7 @@ class CurCommandDispatcher(QObject): if tab is not None: tab.stop() - @cmdutils.register(name='print') + @cmdutils.register(instance='browser', name='print') def printpage(self, count=None): """Print the current/[count]th tab. @@ -557,7 +559,7 @@ class CurCommandDispatcher(QObject): preview.paintRequested.connect(tab.print) preview.exec_() - @cmdutils.register() + @cmdutils.register(instance='browser') def back(self, count=1): """Go back in the history of the current tab. @@ -571,7 +573,7 @@ class CurCommandDispatcher(QObject): for i in range(count): # pylint: disable=unused-variable self.tabs.currentWidget().back() - @cmdutils.register() + @cmdutils.register(instance='browser') def forward(self, count=1): """Go forward in the history of the current tab. @@ -596,7 +598,7 @@ class CurCommandDispatcher(QObject): """ self.tabs.currentWidget().findText(text, flags) - @cmdutils.register(hide=True) + @cmdutils.register(instance='browser', hide=True) def scroll(self, dx, dy, count=1): """Scroll the current tab by count * dx/dy. @@ -612,7 +614,7 @@ class CurCommandDispatcher(QObject): dy = int(count) * float(dy) self.tabs.currentWidget().page_.mainFrame().scroll(dx, dy) - @cmdutils.register(name='scroll_perc_x', hide=True) + @cmdutils.register(instance='browser', name='scroll_perc_x', hide=True) def scroll_percent_x(self, perc=None, count=None): """Scroll the current tab to a specific percent of the page (horiz). @@ -625,7 +627,7 @@ class CurCommandDispatcher(QObject): """ self._scroll_percent(perc, count, Qt.Horizontal) - @cmdutils.register(name='scroll_perc_y', hide=True) + @cmdutils.register(instance='browser', name='scroll_perc_y', hide=True) def scroll_percent_y(self, perc=None, count=None): """Scroll the current tab to a specific percent of the page (vert). @@ -638,7 +640,7 @@ class CurCommandDispatcher(QObject): """ self._scroll_percent(perc, count, Qt.Vertical) - @cmdutils.register(hide=True) + @cmdutils.register(instance='browser', hide=True) def scroll_page(self, mx, my, count=1): """Scroll the frame page-wise. @@ -654,7 +656,7 @@ class CurCommandDispatcher(QObject): page.mainFrame().scroll(int(count) * float(mx) * size.width(), int(count) * float(my) * size.height()) - @cmdutils.register() + @cmdutils.register(instance='browser') def yank(self, sel=False): """Yank the current url to the clipboard or primary selection. @@ -674,7 +676,7 @@ class CurCommandDispatcher(QObject): self.temp_message.emit('URL yanked to {}'.format( 'primary selection' if sel else 'clipboard')) - @cmdutils.register(name='yanktitle') + @cmdutils.register(instance='browser', name='yanktitle') def yank_title(self, sel=False): """Yank the current title to the clipboard or primary selection. @@ -694,7 +696,7 @@ class CurCommandDispatcher(QObject): self.temp_message.emit('Title yanked to {}'.format( 'primary selection' if sel else 'clipboard')) - @cmdutils.register(name='zoomin') + @cmdutils.register(instance='browser', name='zoomin') def zoom_in(self, count=1): """Zoom in in the current tab. @@ -705,7 +707,7 @@ class CurCommandDispatcher(QObject): tab = self.tabs.currentWidget() tab.zoom(count) - @cmdutils.register(name='zoomout') + @cmdutils.register(instance='browser', name='zoomout') def zoom_out(self, count=1): """Zoom out in the current tab.