Merge branch 'master' of ssh://lupin/qutebrowser
This commit is contained in:
commit
df98318e6b
@ -18,9 +18,10 @@ It was inspired by other browsers/addons like dwb and Vimperator/Pentadactyl.
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
In addition to the topics mentioned in that README, the following documents are
|
||||
In addition to the topics mentioned in this README, the following documents are
|
||||
available:
|
||||
|
||||
* link:doc/quickstart.asciidoc[Quick start guide]
|
||||
* link:doc/FAQ.asciidoc[Frequently asked questions]
|
||||
* link:doc/HACKING.asciidoc[HACKING]
|
||||
* link:doc/readme.asciidoc[Reporting segfaults]
|
||||
@ -165,6 +166,22 @@ As soon as v0.1 is out, a standalone .exe (built with
|
||||
http://cx-freeze.sourceforge.net/[cx_Freeze]) will be provided. In the
|
||||
meantime, you can simply ask in IRC if you need one.
|
||||
|
||||
Donating
|
||||
--------
|
||||
|
||||
Working on qutebrowser is a very rewarding hobby, but like (nearly) all hobbies
|
||||
it also costs some money. Namely I have to pay for the server and domain, and
|
||||
do occasional hardware upgrades footnote:[It turned out a 160 GB SSD is rather
|
||||
small - the VMs and custom Qt builds I use for testing/developing qutebrowser
|
||||
need about 100 GB of space].
|
||||
|
||||
If you want to give me a beer or a pizza back, I'm trying to make it as easy as
|
||||
possible for you to do so. If some other way would be easier for you, please
|
||||
get in touch!
|
||||
|
||||
* PayPal: me@the-compiler.org
|
||||
* Bitcoin: link:bitcoin:1PMzbcetAHfpxoXww8Bj5XqquHtVvMjJtE[1PMzbcetAHfpxoXww8Bj5XqquHtVvMjJtE]
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
|
@ -421,7 +421,8 @@ displaying it to the user.
|
||||
* Mention in the docstring whether your function needs a URL string or a
|
||||
`QUrl`.
|
||||
* Call `ensure_valid` from `utils.qtutils` whenever getting or creating a
|
||||
`QUrl` and take appropriate action if not.
|
||||
`QUrl` and take appropriate action if not. Note the URL of the current page
|
||||
always could be an invalid QUrl (if nothing is loaded yet).
|
||||
|
||||
|
||||
Style conventions
|
||||
|
@ -6,6 +6,7 @@ Documentation
|
||||
|
||||
The following help pages are currently available:
|
||||
|
||||
* link:quickstart.html[Quick start guide]
|
||||
* link:FAQ.html[Frequently asked questions]
|
||||
* link:commands.html[Documentation of commands]
|
||||
* link:settings.html[Documentation of settings]
|
||||
|
@ -40,7 +40,7 @@ What to do now
|
||||
* Press `:` to get the commandline. Press `o`/`O` to open a new page (with `O`
|
||||
in a new tab). Use `H` and `L` to go back/forward and `J`/`K` to focus the
|
||||
next/previous tab. See `~/.config/qutebrowser/keys.conf` for all mapped keys.
|
||||
* Subscribe to
|
||||
* Subscribe to
|
||||
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser[the mailinglist]
|
||||
where there are weekly "what's new in qutebrowser" posts.
|
||||
* Let me know what features you are missing or things that need (even small!)
|
||||
|
@ -263,6 +263,21 @@ class Application(QApplication):
|
||||
else:
|
||||
tabbed_browser.tabopen(url)
|
||||
|
||||
# Open quickstart if it's the first start
|
||||
state_config = objreg.get('state-config')
|
||||
try:
|
||||
quickstart_done = state_config['general']['quickstart-done'] == '1'
|
||||
except KeyError:
|
||||
quickstart_done = False
|
||||
if not quickstart_done:
|
||||
tabbed_browser.tabopen(
|
||||
QUrl('http://www.qutebrowser.org/quickstart.html'))
|
||||
try:
|
||||
state_config.add_section('general')
|
||||
except configparser.DuplicateSectionError:
|
||||
pass
|
||||
state_config['general']['quickstart-done'] = '1'
|
||||
|
||||
def _python_hacks(self):
|
||||
"""Get around some PyQt-oddities by evil hacks.
|
||||
|
||||
|
@ -92,6 +92,11 @@ class CommandDispatcher:
|
||||
tab: Whether to open in a new tab.
|
||||
background: Whether to open in the background.
|
||||
"""
|
||||
if not url.isValid():
|
||||
errstr = "Invalid URL {}"
|
||||
if url.errorString():
|
||||
errstr += " - {}".format(url.errorString())
|
||||
raise cmdexc.CommandError(errstr)
|
||||
tabbed_browser = objreg.get('tabbed-browser')
|
||||
if tab and background:
|
||||
raise cmdexc.CommandError("Only one of -t/-b can be given!")
|
||||
@ -715,9 +720,6 @@ class CommandDispatcher:
|
||||
"""
|
||||
urlstr = quickmarks.get(name)
|
||||
url = QUrl(urlstr)
|
||||
if not url.isValid():
|
||||
raise cmdexc.CommandError("Invalid URL {} ({})".format(
|
||||
urlstr, url.errorString()))
|
||||
self._open(url, tab, bg)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', name='inspector')
|
||||
|
@ -359,7 +359,9 @@ class DownloadManager(QObject):
|
||||
url: The URL to get, as QUrl
|
||||
page: The QWebPage to get the download from.
|
||||
"""
|
||||
qtutils.ensure_valid(url)
|
||||
if not url.isValid():
|
||||
urlutils.invalid_url_error(url, "start download")
|
||||
return
|
||||
req = QNetworkRequest(url)
|
||||
reply = page.networkAccessManager().get(req)
|
||||
self.fetch(reply)
|
||||
|
@ -327,7 +327,6 @@ class HintManager(QObject):
|
||||
Args:
|
||||
url: The URL to open as a QURL.
|
||||
"""
|
||||
qtutils.ensure_valid(url)
|
||||
sel = self._context.target == Target.yank_primary
|
||||
mode = QClipboard.Selection if sel else QClipboard.Clipboard
|
||||
urlstr = url.toString(QUrl.FullyEncoded | QUrl.RemovePassword)
|
||||
@ -341,7 +340,6 @@ class HintManager(QObject):
|
||||
Args:
|
||||
url: The URL to open as a QUrl.
|
||||
"""
|
||||
qtutils.ensure_valid(url)
|
||||
urlstr = url.toDisplayString(QUrl.FullyEncoded)
|
||||
args = self._context.get_args(urlstr)
|
||||
message.set_cmd_text(' '.join(args))
|
||||
@ -357,19 +355,16 @@ class HintManager(QObject):
|
||||
message.error("No suitable link found for this element.",
|
||||
immediately=True)
|
||||
return
|
||||
qtutils.ensure_valid(url)
|
||||
objreg.get('download-manager').get(url, elem.webFrame().page())
|
||||
|
||||
def _call_userscript(self, url):
|
||||
"""Call an userscript from a hint."""
|
||||
qtutils.ensure_valid(url)
|
||||
cmd = self._context.args[0]
|
||||
args = self._context.args[1:]
|
||||
userscripts.run(cmd, *args, url=url)
|
||||
|
||||
def _spawn(self, url):
|
||||
"""Spawn a simple command from a hint."""
|
||||
qtutils.ensure_valid(url)
|
||||
urlstr = url.toString(QUrl.FullyEncoded | QUrl.RemovePassword)
|
||||
args = self._context.get_args(urlstr)
|
||||
subprocess.Popen(args)
|
||||
@ -396,6 +391,7 @@ class HintManager(QObject):
|
||||
if baseurl is None:
|
||||
baseurl = self._context.baseurl
|
||||
url = baseurl.resolved(url)
|
||||
qtutils.ensure_valid(url)
|
||||
return url
|
||||
|
||||
def _find_prevnext(self, frame, prev=False):
|
||||
@ -511,7 +507,6 @@ class HintManager(QObject):
|
||||
if url is None:
|
||||
raise cmdexc.CommandError("No {} links found!".format(
|
||||
"prev" if prev else "forward"))
|
||||
qtutils.ensure_valid(url)
|
||||
if newtab:
|
||||
objreg.get('tabbed-browser').tabopen(url, background=False)
|
||||
else:
|
||||
|
@ -64,7 +64,9 @@ def prompt_save(url):
|
||||
Args:
|
||||
url: The quickmark url as a QUrl.
|
||||
"""
|
||||
qtutils.ensure_valid(url)
|
||||
if not url.isValid():
|
||||
urlutils.invalid_url_error(url, "save quickmark")
|
||||
return
|
||||
urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
|
||||
message.ask_async("Add quickmark:", usertypes.PromptMode.text,
|
||||
functools.partial(quickmark_add, urlstr))
|
||||
|
@ -28,7 +28,7 @@ from PyQt5.QtCore import QUrl
|
||||
from PyQt5.QtNetwork import QHostInfo
|
||||
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import log, qtutils
|
||||
from qutebrowser.utils import log, qtutils, message
|
||||
|
||||
|
||||
# FIXME: we probably could raise some exceptions on invalid URLs
|
||||
@ -262,6 +262,17 @@ def qurl_from_user_input(urlstr):
|
||||
return QUrl('http://[{}]{}'.format(ipstr, rest))
|
||||
|
||||
|
||||
def invalid_url_error(url, action):
|
||||
"""Display an error message for an URL."""
|
||||
if url.isValid():
|
||||
raise ValueError("Calling invalid_url_error with valid URL {}".format(
|
||||
url.toDisplayString()))
|
||||
errstring = "Trying to {} with invalid URL".format(action)
|
||||
if url.errorString():
|
||||
errstring += " - {}".format(url.errorString())
|
||||
message.error(errstring)
|
||||
|
||||
|
||||
class FuzzyUrlError(Exception):
|
||||
|
||||
"""Exception raised by fuzzy_url on problems."""
|
||||
|
@ -86,7 +86,7 @@ class ConsoleLineEdit(misc.CommandLineEdit):
|
||||
"""Push a line to the interpreter."""
|
||||
self._buffer.append(line)
|
||||
source = '\n'.join(self._buffer)
|
||||
self.write.emit(self._curprompt() + line)
|
||||
self.write.emit(self._curprompt() + line + '\n')
|
||||
# We do two special things with the contextmanagers here:
|
||||
# - We replace stdout/stderr to capture output. Even if we could
|
||||
# override InteractiveInterpreter's write method, most things are
|
||||
@ -152,11 +152,12 @@ class ConsoleLineEdit(misc.CommandLineEdit):
|
||||
|
||||
class ConsoleTextEdit(QTextEdit):
|
||||
|
||||
"""Custom QTextEdit for console input."""
|
||||
"""Custom QTextEdit for console output."""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setAcceptRichText(False)
|
||||
self.setLineWrapMode(QTextEdit.NoWrap)
|
||||
self.setReadOnly(True)
|
||||
config.on_change(self.update_font, 'fonts', 'debug-console')
|
||||
self.update_font()
|
||||
@ -184,7 +185,7 @@ class ConsoleWidget(QWidget):
|
||||
super().__init__(parent)
|
||||
self._lineedit = ConsoleLineEdit(self)
|
||||
self._output = ConsoleTextEdit()
|
||||
self._lineedit.write.connect(self._output.append)
|
||||
self._lineedit.write.connect(self._output.insertPlainText)
|
||||
self._vbox = QVBoxLayout()
|
||||
self._vbox.setSpacing(0)
|
||||
self._vbox.addWidget(self._output)
|
||||
|
@ -247,11 +247,13 @@ class TabbedBrowser(tabwidget.TabWidget):
|
||||
self._now_focused = None
|
||||
if tab is objreg.get('last-focused-tab', None):
|
||||
objreg.delete('last-focused-tab')
|
||||
if not tab.cur_url.isEmpty():
|
||||
qtutils.ensure_valid(tab.cur_url)
|
||||
if tab.cur_url.isValid():
|
||||
history_data = qtutils.serialize(tab.history())
|
||||
entry = UndoEntry(tab.cur_url, history_data)
|
||||
self._undo_stack.append(entry)
|
||||
else:
|
||||
urlutils.invalid_url_error(url, "saving tab")
|
||||
return
|
||||
tab.shutdown()
|
||||
self._tabs.remove(tab)
|
||||
self.removeTab(idx)
|
||||
|
@ -335,10 +335,13 @@ class WebView(QWebView):
|
||||
|
||||
@pyqtSlot('QUrl')
|
||||
def on_url_changed(self, url):
|
||||
"""Update cur_url when URL has changed."""
|
||||
qtutils.ensure_valid(url)
|
||||
self.cur_url = url
|
||||
self.url_text_changed.emit(url.toDisplayString())
|
||||
"""Update cur_url when URL has changed.
|
||||
|
||||
If the URL is invalid, we just ignore it here.
|
||||
"""
|
||||
if url.isValid():
|
||||
self.cur_url = url
|
||||
self.url_text_changed.emit(url.toDisplayString())
|
||||
|
||||
@pyqtSlot('QMouseEvent')
|
||||
def on_mouse_event(self, evt):
|
||||
|
@ -65,6 +65,7 @@ def main(colors=False):
|
||||
utils.use_color = colors
|
||||
asciidoc_files = [
|
||||
('doc/FAQ.asciidoc', 'qutebrowser/html/doc/FAQ.html'),
|
||||
('doc/quickstart.asciidoc', 'qutebrowser/html/doc/quickstart.html'),
|
||||
]
|
||||
try:
|
||||
os.mkdir('qutebrowser/html/doc')
|
||||
|
Loading…
Reference in New Issue
Block a user