Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9d5b2df0c | ||
|
|
d6fd5a817e | ||
|
|
301186d407 | ||
|
|
ab121a98da | ||
|
|
a463038834 | ||
|
|
22761b4373 | ||
|
|
78f6f3a0e1 | ||
|
|
6166ea51e2 | ||
|
|
4d4065dfac | ||
|
|
81f350ee99 | ||
|
|
4b98e6e9ce | ||
|
|
11f8ab1f85 | ||
|
|
0449da048f | ||
|
|
c78e938dea | ||
|
|
99fb8a5d87 | ||
|
|
b1e0b8f119 | ||
|
|
8d49e001e9 | ||
|
|
965c176acf | ||
|
|
896da1c27e | ||
|
|
8f33fcfc52 | ||
|
|
91b0a33ab0 | ||
|
|
b059f4058f | ||
|
|
b63ce438b4 |
@@ -1,19 +0,0 @@
|
||||
shallow_clone: true
|
||||
version: '{branch}-{build}'
|
||||
cache:
|
||||
- C:\projects\qutebrowser\.cache
|
||||
build: off
|
||||
environment:
|
||||
PYTHONUNBUFFERED: 1
|
||||
PYTHON: C:\Python36\python.exe
|
||||
matrix:
|
||||
- TESTENV: py36-pyqt59
|
||||
- TESTENV: pylint
|
||||
|
||||
install:
|
||||
- '%PYTHON% -m pip install -U pip'
|
||||
- '%PYTHON% -m pip install -r misc\requirements\requirements-tox.txt'
|
||||
- 'set PATH=%PATH%;C:\Python36'
|
||||
|
||||
test_script:
|
||||
- '%PYTHON% -m tox -e %TESTENV%'
|
||||
@@ -1,7 +0,0 @@
|
||||
coverage:
|
||||
status:
|
||||
project: off
|
||||
patch: off
|
||||
changes: off
|
||||
|
||||
comment: off
|
||||
18
.coveragerc
@@ -1,18 +0,0 @@
|
||||
[run]
|
||||
source = qutebrowser
|
||||
branch = true
|
||||
omit =
|
||||
qutebrowser/__main__.py
|
||||
*/__init__.py
|
||||
qutebrowser/resources.py
|
||||
|
||||
[report]
|
||||
exclude_lines =
|
||||
pragma: no cover
|
||||
def __repr__
|
||||
raise AssertionError
|
||||
raise NotImplementedError
|
||||
if __name__ == ["']__main__["']:
|
||||
|
||||
[xml]
|
||||
output=coverage.xml
|
||||
@@ -1,17 +0,0 @@
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
charset = utf-8
|
||||
|
||||
max_line_length = 79
|
||||
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.yml]
|
||||
indent_size = 2
|
||||
|
||||
[*.feature]
|
||||
max_line_length = 9999
|
||||
|
||||
63
.flake8
@@ -1,50 +1,19 @@
|
||||
# vim: ft=dosini fileencoding=utf-8:
|
||||
|
||||
[flake8]
|
||||
exclude = .*,__pycache__,resources.py
|
||||
# E128: continuation line under-indented for visual indent
|
||||
# E226: missing whitespace around arithmetic operator
|
||||
# E241: Multiple spaces after ,
|
||||
# E265: Block comment should start with '#'
|
||||
# E501: Line too long
|
||||
# E402: module level import not at top of file
|
||||
# E266: too many leading '#' for block comment
|
||||
# E722: do not use bare except
|
||||
# E731: do not assign a lambda expression, use a def
|
||||
# (for pytest's __tracebackhide__)
|
||||
# checked by pylint:
|
||||
# F401: Unused import
|
||||
# N802: function name should be lowercase
|
||||
# N806: variable in function should be lowercase
|
||||
# P101: format string does contain unindexed parameters
|
||||
# P102: docstring does contain unindexed parameters
|
||||
# P103: other string does contain unindexed parameters
|
||||
# D102: Missing docstring in public method (will be handled by others)
|
||||
# D103: Missing docstring in public function (will be handled by others)
|
||||
# D104: Missing docstring in public package (will be handled by others)
|
||||
# D105: Missing docstring in magic method (will be handled by others)
|
||||
# D209: Blank line before closing """ (removed from PEP257)
|
||||
# D211: No blank lines allowed before class docstring
|
||||
# (PEP257 got changed, but let's stick to the old standard)
|
||||
# D402: First line should not be function's signature (false-positives)
|
||||
# D403: First word of the first line should be properly capitalized
|
||||
# (false-positives)
|
||||
ignore =
|
||||
E128,E226,E265,E501,E402,E266,E722,E731,
|
||||
F401,
|
||||
N802,
|
||||
P101,P102,P103,
|
||||
D102,D103,D104,D105,D209,D211,D402,D403
|
||||
min-version = 3.4.0
|
||||
max-complexity = 12
|
||||
putty-auto-ignore = True
|
||||
putty-ignore =
|
||||
/# pylint: disable=invalid-name/ : +N801,N806
|
||||
/# pragma: no mccabe/ : +C901
|
||||
tests/*/test_*.py : +D100,D101,D401
|
||||
tests/conftest.py : +F403
|
||||
tests/unit/browser/test_history.py : +N806
|
||||
tests/helpers/fixtures.py : +N806
|
||||
tests/unit/browser/webkit/http/test_content_disposition.py : +D400
|
||||
scripts/dev/ci/appveyor_install.py : +FI53
|
||||
# FIXME:conf
|
||||
tests/unit/completion/test_models.py : +F821
|
||||
copyright-check = True
|
||||
copyright-regexp = # Copyright [\d-]+ .*
|
||||
copyright-min-file-size = 110
|
||||
# E501: Line too long
|
||||
# F821: undefined name
|
||||
# F841: unused variable
|
||||
# E222: Multiple spaces after operator
|
||||
# F811: Redifiniton
|
||||
# W292: No newline at end of file
|
||||
# E701: multiple statements on one line
|
||||
# E702: multiple statements on one line
|
||||
# E225: missing whitespace around operator
|
||||
ignore=E241,E265,F401,E501,F821,F841,E222,F811,W292,E701,E702,E225
|
||||
max_complexity = 12
|
||||
exclude = ez_setup.py
|
||||
|
||||
8
.github/CODEOWNERS
vendored
@@ -1,8 +0,0 @@
|
||||
qutebrowser/browser/history.py @rcorre
|
||||
qutebrowser/completion/* @rcorre
|
||||
qutebrowser/misc/sql.py @rcorre
|
||||
tests/end2end/features/completion.feature @rcorre
|
||||
tests/end2end/features/test_completion_bdd.py @rcorre
|
||||
tests/unit/browser/test_history.py @rcorre
|
||||
tests/unit/completion/* @rcorre
|
||||
tests/unit/misc/test_sql.py @rcorre
|
||||
9
.github/CONTRIBUTING.asciidoc
vendored
@@ -1,9 +0,0 @@
|
||||
- Before you start to work on something, please leave a comment on the relevant
|
||||
issue (or open one). This makes sure there is no duplicate work done.
|
||||
|
||||
- Either run the testsuite locally, or keep an eye on Travis CI / AppVeyor
|
||||
after pushing changes.
|
||||
|
||||
See the full contribution docs for details:
|
||||
|
||||
include::../doc/contributing.asciidoc[]
|
||||
2
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,2 +0,0 @@
|
||||
<!-- If this is a bug report, please remember to mention your version info from
|
||||
`:open qute:version` or `qutebrowser --version` -->
|
||||
26
.gitignore
vendored
@@ -1,7 +1,5 @@
|
||||
__pycache__
|
||||
*.py~
|
||||
*.pyc
|
||||
*.swp
|
||||
/build
|
||||
/dist
|
||||
/qutebrowser.egg-info
|
||||
@@ -12,30 +10,6 @@ __pycache__
|
||||
/setuptools-*.egg
|
||||
/setuptools-*.zip
|
||||
/qutebrowser/git-commit-id
|
||||
/qutebrowser/3rdparty
|
||||
/doc/*.html
|
||||
/README.html
|
||||
/qutebrowser/html/doc/
|
||||
/qutebrowser/html/*.html
|
||||
/.venv*
|
||||
/.coverage
|
||||
/htmlcov
|
||||
/coverage.xml
|
||||
/.coverage.*
|
||||
/.tox
|
||||
/testresults.html
|
||||
/.cache
|
||||
/.testmondata
|
||||
/.hypothesis
|
||||
/prof
|
||||
/venv
|
||||
TODO
|
||||
/scripts/testbrowser_cpp/webkit/Makefile
|
||||
/scripts/testbrowser_cpp/webkit/main.o
|
||||
/scripts/testbrowser_cpp/webkit/testbrowser
|
||||
/scripts/testbrowser_cpp/webkit/.qmake.stash
|
||||
/scripts/testbrowser_cpp/webengine/Makefile
|
||||
/scripts/testbrowser_cpp/webengine/main.o
|
||||
/scripts/testbrowser_cpp/webengine/testbrowser
|
||||
/scripts/testbrowser_cpp/webengine/.qmake.stash
|
||||
/scripts/dev/pylint_checkers/qute_pylint.egg-info
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
[pydocstyle]
|
||||
# Disabled checks:
|
||||
# D102: Missing docstring in public method (will be handled by others)
|
||||
# D103: Missing docstring in public function (will be handled by others)
|
||||
# D104: Missing docstring in public package (will be handled by others)
|
||||
# D105: Missing docstring in magic method (will be handled by others)
|
||||
# D209: Blank line before closing """ (removed from PEP257)
|
||||
# D211: No blank lines allowed before class docstring
|
||||
# (PEP257 got changed, but let's stick to the old standard)
|
||||
# D402: First line should not be function's signature (false-positives)
|
||||
ignore = D102,D103,D104,D105,D209,D211,D402
|
||||
match = (?!resources|test_*).*\.py
|
||||
inherit = false
|
||||
68
.pylintrc
@@ -1,78 +1,56 @@
|
||||
# vim: ft=dosini fileencoding=utf-8:
|
||||
|
||||
[MASTER]
|
||||
ignore=resources.py
|
||||
extension-pkg-whitelist=PyQt5,sip
|
||||
load-plugins=qute_pylint.config,
|
||||
qute_pylint.modeline,
|
||||
qute_pylint.openencoding,
|
||||
qute_pylint.settrace,
|
||||
pylint.extensions.bad_builtin,
|
||||
pylint.extensions.docstyle
|
||||
persistent=n
|
||||
ignore=ez_setup.py
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
enable=all
|
||||
disable=no-self-use,
|
||||
super-on-old-class,
|
||||
old-style-class,
|
||||
abstract-class-little-used,
|
||||
bad-builtin,
|
||||
star-args,
|
||||
fixme,
|
||||
global-statement,
|
||||
no-init,
|
||||
locally-disabled,
|
||||
locally-enabled,
|
||||
too-many-ancestors,
|
||||
too-few-public-methods,
|
||||
too-many-public-methods,
|
||||
cyclic-import,
|
||||
bad-option-value,
|
||||
bad-continuation,
|
||||
too-many-instance-attributes,
|
||||
unnecessary-lambda,
|
||||
blacklisted-name,
|
||||
too-many-lines,
|
||||
logging-format-interpolation,
|
||||
broad-except,
|
||||
bare-except,
|
||||
eval-used,
|
||||
exec-used,
|
||||
ungrouped-imports,
|
||||
suppressed-message,
|
||||
too-many-return-statements,
|
||||
duplicate-code,
|
||||
wrong-import-position,
|
||||
no-else-return,
|
||||
# https://github.com/PyCQA/pylint/issues/1698
|
||||
unsupported-membership-test,
|
||||
unsupported-assignment-operation,
|
||||
unsubscriptable-object
|
||||
too-many-lines
|
||||
|
||||
[BASIC]
|
||||
function-rgx=[a-z_][a-z0-9_]{2,50}$
|
||||
module-rgx=(__)?[a-z][a-z0-9_]*(__)?$
|
||||
function-rgx=([a-z_][a-z0-9_]{2,30}|setUpModule|tearDownModule)$
|
||||
const-rgx=[A-Za-z_][A-Za-z0-9_]{0,30}$
|
||||
method-rgx=[a-z_][A-Za-z0-9_]{1,50}$
|
||||
method-rgx=[a-z_][A-Za-z0-9_]{2,40}$
|
||||
attr-rgx=[a-z_][a-z0-9_]{0,30}$
|
||||
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{1,30}|(__.*__))$
|
||||
argument-rgx=[a-z_][a-z0-9_]{0,30}$
|
||||
variable-rgx=[a-z_][a-z0-9_]{0,30}$
|
||||
docstring-min-length=3
|
||||
no-docstring-rgx=(^_|^main$)
|
||||
class-attribute-rgx=[A-Za-z_][A-Za-z0-9_]{1,30}$
|
||||
inlinevar-rgx=[a-z_][a-z0-9_]*$
|
||||
|
||||
[FORMAT]
|
||||
max-line-length=79
|
||||
ignore-long-lines=(<?https?://|^# Copyright 201\d)
|
||||
expected-line-ending-format=LF
|
||||
ignore-long-lines=<?https?://
|
||||
|
||||
[SIMILARITIES]
|
||||
min-similarity-lines=8
|
||||
|
||||
[VARIABLES]
|
||||
dummy-variables-rgx=_.*
|
||||
|
||||
[CLASSES]
|
||||
defining-attr-methods=__init__,__new__,setUp
|
||||
|
||||
[DESIGN]
|
||||
max-args=10
|
||||
|
||||
[CLASSES]
|
||||
valid-metaclass-classmethod-first-arg=cls
|
||||
|
||||
[TYPECHECK]
|
||||
ignored-modules=PyQt5,PyQt5.QtWebKit
|
||||
ignored-classes=_CountingAttr
|
||||
|
||||
[IMPORTS]
|
||||
# WORKAROUND
|
||||
# For some reason, pylint doesn't know about some Python 3 modules on
|
||||
# AppVeyor...
|
||||
known-standard-library=faulthandler,http,enum,tokenize,posixpath,importlib,types
|
||||
ignored-classes=WebElementWrapper,AnsiCodes,UnsetObject
|
||||
|
||||
20
.run_checks
Normal file
@@ -0,0 +1,20 @@
|
||||
# vim: ft=dosini
|
||||
|
||||
[DEFAULT]
|
||||
targets=qutebrowser,scripts
|
||||
|
||||
[pep257]
|
||||
# D102: Docstring missing, will be handled by others
|
||||
# D209: Blank line before closing """ (removed from PEP257)
|
||||
# D402: First line should not be function's signature (false-positives)
|
||||
disable=D102,D209,D402
|
||||
exclude=test_.*
|
||||
|
||||
[pylint]
|
||||
args=--output-format=colorized,--reports=no,--rcfile=.pylintrc
|
||||
plugins=config,crlf,modeline,settrace,openencoding
|
||||
exclude=resources.py
|
||||
|
||||
[flake8]
|
||||
args=--config=.flake8
|
||||
exclude=resources.py
|
||||
86
.travis.yml
@@ -1,86 +0,0 @@
|
||||
sudo: false
|
||||
dist: trusty
|
||||
language: python
|
||||
group: edge
|
||||
python: 3.6
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
env: DOCKER=archlinux
|
||||
services: docker
|
||||
- os: linux
|
||||
env: DOCKER=archlinux-webengine QUTE_BDD_WEBENGINE=true
|
||||
services: docker
|
||||
- os: linux
|
||||
env: TESTENV=py36-pyqt571
|
||||
- os: linux
|
||||
env: TESTENV=py36-pyqt58
|
||||
- os: linux
|
||||
python: 3.5
|
||||
env: TESTENV=py35-pyqt59
|
||||
- os: linux
|
||||
env: TESTENV=py36-pyqt59-cov
|
||||
- os: osx
|
||||
env: TESTENV=py36 OSX=sierra
|
||||
osx_image: xcode8.3
|
||||
language: generic
|
||||
# https://github.com/qutebrowser/qutebrowser/issues/2013
|
||||
# - os: osx
|
||||
# env: TESTENV=py35 OSX=yosemite
|
||||
# osx_image: xcode6.4
|
||||
- os: linux
|
||||
env: TESTENV=pylint PYTHON=python3.6
|
||||
- os: linux
|
||||
env: TESTENV=flake8
|
||||
- os: linux
|
||||
env: TESTENV=docs
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- asciidoc
|
||||
- os: linux
|
||||
env: TESTENV=vulture
|
||||
- os: linux
|
||||
env: TESTENV=misc
|
||||
- os: linux
|
||||
env: TESTENV=pyroma
|
||||
- os: linux
|
||||
env: TESTENV=check-manifest
|
||||
- os: linux
|
||||
env: TESTENV=eslint
|
||||
language: node_js
|
||||
python: null
|
||||
node_js: "lts/*"
|
||||
fast_finish: true
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.cache/pip
|
||||
- $HOME/build/qutebrowser/qutebrowser/.cache
|
||||
|
||||
install:
|
||||
- bash scripts/dev/ci/travis_install.sh
|
||||
- ulimit -c unlimited
|
||||
|
||||
script:
|
||||
- bash scripts/dev/ci/travis_run.sh
|
||||
|
||||
after_success:
|
||||
- '[[ $TESTENV == *-cov ]] && codecov -e TESTENV -X gcov'
|
||||
|
||||
after_failure:
|
||||
- bash scripts/dev/ci/travis_backtrace.sh
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
- https://buildtimetrend.herokuapp.com/travis
|
||||
irc:
|
||||
channels:
|
||||
- "chat.freenode.net#qutebrowser-dev"
|
||||
on_success: always
|
||||
on_failure: always
|
||||
skip_join: true
|
||||
template:
|
||||
- "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}"
|
||||
- "%{compare_url} - %{build_url}"
|
||||
62
MANIFEST.in
@@ -1,45 +1,17 @@
|
||||
recursive-include qutebrowser *.py
|
||||
recursive-include qutebrowser/img *.svg *.png
|
||||
recursive-include qutebrowser/test *.py
|
||||
recursive-include qutebrowser/javascript *.js
|
||||
graft qutebrowser/html
|
||||
graft qutebrowser/3rdparty
|
||||
graft icons
|
||||
graft doc/img
|
||||
graft misc/apparmor
|
||||
graft misc/userscripts
|
||||
recursive-include scripts *.py *.sh
|
||||
include qutebrowser/utils/testfile
|
||||
include qutebrowser/git-commit-id
|
||||
include LICENSE doc/* README.asciidoc
|
||||
include misc/qutebrowser.desktop
|
||||
include requirements.txt
|
||||
include tox.ini
|
||||
include qutebrowser.py
|
||||
include misc/cheatsheet.svg
|
||||
include qutebrowser/config/configdata.yml
|
||||
|
||||
prune www
|
||||
prune scripts/dev
|
||||
prune scripts/testbrowser_cpp
|
||||
prune .github
|
||||
exclude scripts/asciidoc2html.py
|
||||
exclude doc/notes
|
||||
recursive-exclude doc *.asciidoc
|
||||
include doc/qutebrowser.1.asciidoc
|
||||
include doc/changelog.asciidoc
|
||||
prune tests
|
||||
prune qutebrowser/3rdparty
|
||||
prune misc/requirements
|
||||
prune misc/docker
|
||||
exclude pytest.ini
|
||||
exclude qutebrowser.rcc
|
||||
exclude qutebrowser/javascript/.eslintrc.yaml
|
||||
exclude qutebrowser/javascript/.eslintignore
|
||||
exclude doc/help
|
||||
exclude .*
|
||||
exclude misc/appveyor_install.py
|
||||
exclude misc/qutebrowser.spec
|
||||
exclude misc/qutebrowser.nsi
|
||||
|
||||
global-exclude __pycache__ *.pyc *.pyo
|
||||
recursive-include qutebrowser/html *.html
|
||||
recursive-include qutebrowser/test *.py
|
||||
recursive-include icons *
|
||||
include qutebrowser/test/testfile
|
||||
include qutebrowser/git-commit-id
|
||||
include COPYING doc/* README.asciidoc
|
||||
include qutebrowser.desktop
|
||||
|
||||
exclude scripts/run_checks.py
|
||||
exclude scripts/cleanup.py
|
||||
exclude scripts/minimal_webkit_testbrowser.py
|
||||
exclude scripts/run_profile.py
|
||||
exclude scripts/generate_authors.sh
|
||||
exclude .flake8
|
||||
exclude .pylintrc
|
||||
exclude doc/notes
|
||||
prune pkg
|
||||
|
||||
221
README.asciidoc
@@ -1,42 +1,36 @@
|
||||
// If you are reading this in plaintext or on PyPi:
|
||||
//
|
||||
// A rendered version is available at:
|
||||
// https://github.com/qutebrowser/qutebrowser/blob/master/README.asciidoc
|
||||
// https://github.com/The-Compiler/qutebrowser/blob/master/README.asciidoc
|
||||
|
||||
qutebrowser
|
||||
===========
|
||||
|
||||
// QUTE_WEB_HIDE
|
||||
image:icons/qutebrowser-64x64.png[qutebrowser logo] *A keyboard-driven, vim-like browser based on PyQt5 and Qt.*
|
||||
image:icons/qutebrowser-64x64.png[] _A keyboard-driven, vim-like browser based
|
||||
on PyQt5 and QtWebKit._
|
||||
|
||||
image:https://img.shields.io/pypi/l/qutebrowser.svg?style=flat["license badge",link="https://github.com/qutebrowser/qutebrowser/blob/master/LICENSE"]
|
||||
image:https://img.shields.io/pypi/v/qutebrowser.svg?style=flat["version badge",link="https://pypi.python.org/pypi/qutebrowser/"]
|
||||
image:https://travis-ci.org/qutebrowser/qutebrowser.svg?branch=master["Build Status", link="https://travis-ci.org/qutebrowser/qutebrowser"]
|
||||
image:https://ci.appveyor.com/api/projects/status/5pyauww2k68bbow2/branch/master?svg=true["AppVeyor build status", link="https://ci.appveyor.com/project/qutebrowser/qutebrowser"]
|
||||
image:https://codecov.io/github/qutebrowser/qutebrowser/coverage.svg?branch=master["coverage badge",link="https://codecov.io/github/qutebrowser/qutebrowser?branch=master"]
|
||||
|
||||
link:https://www.qutebrowser.org[website] | link:https://blog.qutebrowser.org[blog] | link:https://github.com/qutebrowser/qutebrowser/releases[releases]
|
||||
// QUTE_WEB_HIDE_END
|
||||
|
||||
qutebrowser is a keyboard-focused browser with a minimal GUI. It's based
|
||||
on Python and PyQt5 and free software, licensed under the GPL.
|
||||
qutebrowser is a keyboard-focused browser with with a minimal GUI. It's based
|
||||
on Python, PyQt5 and QtWebKit and free software, licensed under the GPL.
|
||||
|
||||
It was inspired by other browsers/addons like dwb and Vimperator/Pentadactyl.
|
||||
|
||||
Screenshots
|
||||
-----------
|
||||
|
||||
image:doc/img/main.png["screenshot 1",width=300,link="doc/img/main.png"]
|
||||
image:doc/img/downloads.png["screenshot 2",width=300,link="doc/img/downloads.png"]
|
||||
image:doc/img/completion.png["screenshot 3",width=300,link="doc/img/completion.png"]
|
||||
image:doc/img/hints.png["screenshot 4",width=300,link="doc/img/hints.png"]
|
||||
image:doc/img/main.png[width=300,link="doc/img/main.png"]
|
||||
image:doc/img/downloads.png[width=300,link="doc/img/downloads.png"]
|
||||
image:doc/img/completion.png[width=300,link="doc/img/completion.png"]
|
||||
image:doc/img/hints.png[width=300,link="doc/img/hints.png"]
|
||||
|
||||
Downloads
|
||||
---------
|
||||
|
||||
See the https://github.com/qutebrowser/qutebrowser/releases[github releases
|
||||
page] for available downloads and the link:doc/install.asciidoc[INSTALL] file for
|
||||
detailed instructions on how to get qutebrowser running on various platforms.
|
||||
See the https://github.com/The-Compiler/qutebrowser/releases[github releases
|
||||
page] for available downloads (currently a source archive, and standalone
|
||||
packages as well as MSI installers for Windows).
|
||||
|
||||
See link:doc/INSTALL.asciidoc[INSTALL] for detailed instructions on how to get
|
||||
qutebrowser running for various platforms.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
@@ -44,17 +38,13 @@ Documentation
|
||||
In addition to the topics mentioned in this README, the following documents are
|
||||
available:
|
||||
|
||||
* https://qutebrowser.org/img/cheatsheet-big.png[Key binding cheatsheet]: +
|
||||
image:https://qutebrowser.org/img/cheatsheet-small.png["qutebrowser key binding cheatsheet",link="https://qutebrowser.org/img/cheatsheet-big.png"]
|
||||
* A http://qutebrowser.org/img/cheatsheet-big.png[keybinding cheatsheet]: +
|
||||
image:http://qutebrowser.org/img/cheatsheet-small.png["qutebrowser keybinding cheatsheet",link="http://qutebrowser.org/img/cheatsheet-big.png"]
|
||||
* link:doc/quickstart.asciidoc[Quick start guide]
|
||||
* https://www.shortcutfoo.com/app/dojos/qutebrowser[Free training course] to remember those key bindings
|
||||
* link:doc/faq.asciidoc[Frequently asked questions]
|
||||
* link:doc/help/configuring.asciidoc[Configuring qutebrowser]
|
||||
* link:doc/contributing.asciidoc[Contributing to qutebrowser]
|
||||
* link:doc/install.asciidoc[Installing qutebrowser]
|
||||
* link:doc/changelog.asciidoc[Change Log]
|
||||
* link:doc/FAQ.asciidoc[Frequently asked questions]
|
||||
* link:doc/HACKING.asciidoc[HACKING]
|
||||
* link:doc/INSTALL.asciidoc[INSTALL]
|
||||
* link:doc/stacktrace.asciidoc[Reporting segfaults]
|
||||
* link:doc/userscripts.asciidoc[How to write userscripts]
|
||||
|
||||
Getting help
|
||||
------------
|
||||
@@ -67,19 +57,11 @@ message to the
|
||||
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser[mailinglist] at
|
||||
mailto:qutebrowser@lists.qutebrowser.org[].
|
||||
|
||||
There's also an https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser-announce[announce-only mailinglist]
|
||||
at mailto:qutebrowser-announce@lists.qutebrowser.org[] (the announcements also
|
||||
get sent to the general qutebrowser@ list).
|
||||
|
||||
If you're a reddit user, there's a
|
||||
https://www.reddit.com/r/qutebrowser/[/r/qutebrowser] subreddit there.
|
||||
|
||||
Contributions / Bugs
|
||||
--------------------
|
||||
|
||||
You want to contribute to qutebrowser? Awesome! Please read
|
||||
link:doc/contributing.asciidoc[the contribution guidelines] for details and
|
||||
useful hints.
|
||||
link:doc/HACKING.asciidoc[HACKING] for details and useful hints.
|
||||
|
||||
If you found a bug or have a feature request, you can report it in several
|
||||
ways:
|
||||
@@ -91,43 +73,34 @@ https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser[mailinglist] at
|
||||
mailto:qutebrowser@lists.qutebrowser.org[].
|
||||
|
||||
For security bugs, please contact me directly at mail@qutebrowser.org, GPG ID
|
||||
https://www.the-compiler.org/pubkey.asc[0xFD55A072].
|
||||
http://www.the-compiler.org/pubkey.asc[0xFD55A072].
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
The following software and libraries are required to run qutebrowser:
|
||||
|
||||
* http://www.python.org/[Python] 3.5 or newer (3.6 recommended)
|
||||
* http://qt.io/[Qt] 5.7.1 or newer with the following modules:
|
||||
- QtCore / qtbase
|
||||
- QtQuick (part of qtbase in some distributions)
|
||||
- QtSQL (part of qtbase in some distributions)
|
||||
- QtOpenGL
|
||||
- QtWebEngine, or
|
||||
- QtWebKit - only the
|
||||
link:https://github.com/annulen/webkit/wiki[updated fork] (5.212) is
|
||||
supported
|
||||
* http://www.riverbankcomputing.com/software/pyqt/intro[PyQt] 5.7.0 or newer
|
||||
(5.9 recommended) for Python 3
|
||||
* http://www.python.org/[Python] 3.4
|
||||
* http://qt-project.org/[Qt] 5.2.0 or newer (5.4 recommended)
|
||||
* QtWebKit
|
||||
* http://www.riverbankcomputing.com/software/pyqt/intro[PyQt] 5.2.0 or newer
|
||||
(5.3.2 recommended) for Python 3
|
||||
* https://pypi.python.org/pypi/setuptools/[pkg_resources/setuptools]
|
||||
* http://fdik.org/pyPEG/[pyPEG2]
|
||||
* http://jinja.pocoo.org/[jinja2]
|
||||
* http://pygments.org/[pygments]
|
||||
* http://pyyaml.org/wiki/PyYAML[PyYAML]
|
||||
* http://www.attrs.org/[attrs]
|
||||
|
||||
The following libraries are optional:
|
||||
To generate the documentation for the `:help` command, when using the git
|
||||
repository (rather than a release), http://asciidoc.org/[asciidoc] is needed.
|
||||
|
||||
* http://cthedot.de/cssutils/[cssutils] (for an improved `:download --mhtml`
|
||||
with QtWebKit).
|
||||
* On Windows, https://pypi.python.org/pypi/colorama/[colorama] for colored log
|
||||
output.
|
||||
* http://asciidoc.org/[asciidoc] to generate the documentation for the `:help`
|
||||
command, when using the git repository (rather than a release).
|
||||
The following libraries are optional and provide colored logging in the
|
||||
console:
|
||||
|
||||
See link:doc/install.asciidoc[the documentation] for directions on how to
|
||||
install qutebrowser and its dependencies.
|
||||
* https://pypi.python.org/pypi/colorlog/[colorlog]
|
||||
* On Windows: https://pypi.python.org/pypi/colorama/[colorama]
|
||||
|
||||
See link:doc/INSTALL.asciidoc[INSTALL] for directions on how to install
|
||||
qutebrowser and its dependencies.
|
||||
|
||||
Donating
|
||||
--------
|
||||
@@ -148,62 +121,79 @@ get in touch!
|
||||
Authors
|
||||
-------
|
||||
|
||||
qutebrowser's primary author is Florian Bruhin (The Compiler), but qutebrowser
|
||||
wouldn't be what it is without the help of
|
||||
https://github.com/qutebrowser/qutebrowser/graphs/contributors[hundreds of contributors]!
|
||||
Contributors, sorted by the number of commits in descending order:
|
||||
|
||||
Additionally, the following people have contributed graphics:
|
||||
// QUTE_AUTHORS_START
|
||||
* Florian Bruhin
|
||||
* Claude
|
||||
* John ShaggyTwoDope Jenkins
|
||||
* rikn00
|
||||
* Brian Jackson
|
||||
* Martin Zimmermann
|
||||
* Error 800
|
||||
* Mathias Fussenegger
|
||||
* Larry Hynes
|
||||
* Johannes Altmanninger
|
||||
* Joel Torstensson
|
||||
* Regina Hug
|
||||
* Peter Vilim
|
||||
* Matthias Lisin
|
||||
* Helen Sherwood-Taylor
|
||||
// QUTE_AUTHORS_END
|
||||
|
||||
* Jad/link:http://yelostudio.com[yelo] (new icon)
|
||||
* WOFall (original icon)
|
||||
* regines (key binding cheatsheet)
|
||||
The following people have contributed graphics:
|
||||
|
||||
Also, thanks to everyone who contributed to one of qutebrowser's
|
||||
link:doc/backers.asciidoc[crowdfunding campaigns]!
|
||||
* WOFall (icon)
|
||||
* regines (keybinding cheatsheet)
|
||||
|
||||
Similar projects
|
||||
----------------
|
||||
Thanks / Similiar projects
|
||||
--------------------------
|
||||
|
||||
Many projects with a similar goal as qutebrowser exist:
|
||||
|
||||
* http://portix.bitbucket.org/dwb/[dwb] (C, GTK+ with WebKit1, currently
|
||||
http://www.reddit.com/r/linux/comments/2huqbc/dwb_abandoned/[unmaintained] -
|
||||
main inspiration for qutebrowser)
|
||||
* https://github.com/fanglingsu/vimb[vimb] (C, GTK+ with WebKit1, active)
|
||||
* http://sourceforge.net/p/vimprobable/wiki/Home/[vimprobable] (C, GTK+ with
|
||||
WebKit1, dead)
|
||||
* http://surf.suckless.org/[surf] (C, GTK+ with WebKit1, active)
|
||||
* https://mason-larobina.github.io/luakit/[luakit] (C/Lua, GTK+ with
|
||||
WebKit1, not very active)
|
||||
* http://pwmt.org/projects/jumanji/[jumanji] (C, GTK+ with WebKit1, not very
|
||||
active)
|
||||
* http://www.uzbl.org/[uzbl] (C, GTK+ with WebKit1/WebKit2, active)
|
||||
* http://conkeror.org/[conkeror] (Javascript, Emacs-like, XULRunner/Gecko,
|
||||
active)
|
||||
* https://github.com/AeroNotix/lispkit[lispkit] (quite new, lisp, GTK+ with
|
||||
WebKit, active)
|
||||
* http://www.vimperator.org/[Vimperator] (Firefox addon)
|
||||
* http://5digits.org/pentadactyl/[Pentadactyl] (Firefox addon)
|
||||
* https://github.com/akhodakivskiy/VimFx[VimFx] (Firefox addon)
|
||||
* https://github.com/1995eaton/chromium-vim[cVim] (Chrome/Chromium addon)
|
||||
* http://vimium.github.io/[vimium] (Chrome/Chromium addon)
|
||||
* https://chrome.google.com/webstore/detail/vichrome/gghkfhpblkcmlkmpcpgaajbbiikbhpdi?hl=en[ViChrome] (Chrome/Chromium addon)
|
||||
* https://github.com/jinzhu/vrome[Vrome] (Chrome/Chromium addon)
|
||||
|
||||
Many projects with a similar goal as qutebrowser exist.
|
||||
Most of them were inspirations for qutebrowser in some way, thanks for that!
|
||||
|
||||
Active
|
||||
~~~~~~
|
||||
Thanks as well to the following projects and people for helping me with
|
||||
problems and helpful hints:
|
||||
|
||||
* https://fanglingsu.github.io/vimb/[vimb] (C, GTK+ with WebKit2)
|
||||
* https://luakit.github.io/luakit/[luakit] (C/Lua, GTK+ with WebKit2)
|
||||
* http://surf.suckless.org/[surf] (C, GTK+ with WebKit1/WebKit2)
|
||||
* http://www.uzbl.org/[uzbl] (C, GTK+ with WebKit1/WebKit2)
|
||||
* Chrome/Chromium addons:
|
||||
https://github.com/1995eaton/chromium-vim[cVim],
|
||||
http://vimium.github.io/[Vimium],
|
||||
https://github.com/brookhong/Surfingkeys[Surfingkeys],
|
||||
https://key.saka.io/[Saka Key]
|
||||
* Firefox addons (based on WebExtensions):
|
||||
https://addons.mozilla.org/en-GB/firefox/addon/vimium-ff/[Vimium-FF] (experimental),
|
||||
https://key.saka.io[Saka Key],
|
||||
https://github.com/cmcaine/tridactyl[Tridactyl] (in early development, working
|
||||
on a https://bugzilla.mozilla.org/show_bug.cgi?id=1215061[better API] for
|
||||
keyboard integration in Firefox).
|
||||
* http://eric-ide.python-projects.org/[eric5] / Detlev Offenbach
|
||||
* https://code.google.com/p/devicenzo/[devicenzo]
|
||||
* portix
|
||||
* seir
|
||||
* nitroxleecher
|
||||
|
||||
Inactive
|
||||
~~~~~~~~
|
||||
Also, thanks to:
|
||||
|
||||
* https://bitbucket.org/portix/dwb[dwb] (C, GTK+ with WebKit1,
|
||||
https://bitbucket.org/portix/dwb/pull-requests/22/several-cleanups-to-increase-portability/diff[unmaintained] -
|
||||
main inspiration for qutebrowser)
|
||||
* http://sourceforge.net/p/vimprobable/wiki/Home/[vimprobable] (C, GTK+ with
|
||||
WebKit1)
|
||||
* http://pwmt.org/projects/jumanji/[jumanji] (C, GTK+ with WebKit1)
|
||||
* http://conkeror.org/[conkeror] (Javascript, Emacs-like, XULRunner/Gecko)
|
||||
* Firefox addons (not based on WebExtensions or no recent activity):
|
||||
http://www.vimperator.org/[Vimperator],
|
||||
http://5digits.org/pentadactyl/[Pentadactyl],
|
||||
https://github.com/akhodakivskiy/VimFx[VimFx],
|
||||
https://github.com/shinglyu/QuantumVim[QuantumVim]
|
||||
* Chrome/Chromium addons:
|
||||
https://chrome.google.com/webstore/detail/vichrome/gghkfhpblkcmlkmpcpgaajbbiikbhpdi?hl=en[ViChrome],
|
||||
https://github.com/jinzhu/vrome[Vrome]
|
||||
* Everyone who had the patience to test qutebrowser before v0.1.
|
||||
* Everyone triaging/fixing my bugs in the
|
||||
https://bugreports.qt-project.org/secure/Dashboard.jspa[Qt bugtracker]
|
||||
* Everyone answering my questions on http://stackoverflow.com/[Stack Overflow]
|
||||
and in IRC.
|
||||
* All the projects which were a great help while developing qutebrowser.
|
||||
|
||||
License
|
||||
-------
|
||||
@@ -219,15 +209,4 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
pdf.js
|
||||
------
|
||||
|
||||
qutebrowser optionally uses https://github.com/mozilla/pdf.js/[pdf.js] to
|
||||
display PDF files in the browser. Windows releases come with a bundled pdf.js.
|
||||
|
||||
pdf.js is distributed under the terms of the Apache License. You can
|
||||
find a copy of the license in `qutebrowser/3rdparty/pdfjs/LICENSE` (in the
|
||||
Windows release or after running `scripts/dev/update_3rdparty.py`), or online
|
||||
http://www.apache.org/licenses/LICENSE-2.0.html[here].
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
117
doc/FAQ.asciidoc
Normal file
@@ -0,0 +1,117 @@
|
||||
Frequently asked questions
|
||||
==========================
|
||||
The Compiler <mail@qutebrowser.org>
|
||||
|
||||
[qanda]
|
||||
What is qutebrowser based on?::
|
||||
qutebrowser uses http://www.python.org/[Python], http://qt-project.org/[Qt]
|
||||
and http://www.riverbankcomputing.com/software/pyqt/intro[PyQt].
|
||||
+
|
||||
The concept of it is largely inspired by http://portix.bitbucket.org/dwb/[dwb]
|
||||
and http://www.vimperator.org/vimperator[Vimperator]. Many actions and
|
||||
keybindings are similar to dwb.
|
||||
|
||||
Why another browser?::
|
||||
It might be hard to believe, but I didn't find any browser which I was
|
||||
happy with, so I started to write my own. Also, I needed a project to get
|
||||
into writing GUI applications with Python and
|
||||
link:http://qt-project.org/[Qt]/link:http://www.riverbankcomputing.com/software/pyqt/intro[PyQt].
|
||||
+
|
||||
Read the next few questions to find out why I was unhappy with existing
|
||||
software.
|
||||
|
||||
What's wrong with link:http://portix.bitbucket.org/dwb/[dwb]/link:http://sourceforge.net/projects/vimprobable/[vimprobable]/link:https://mason-larobina.github.io/luakit/[luakit]/link:http://pwmt.org/projects/jumanji/[jumanji]/... (projects based on WebKitGTK)?::
|
||||
Most of them are based on the http://webkitgtk.org/[WebKitGTK+]
|
||||
http://webkitgtk.org/reference/webkitgtk/stable/index.html[WebKit1] API,
|
||||
which causes a lot of crashes. As the GTK API using WebKit1 is
|
||||
https://lists.webkit.org/pipermail/webkit-gtk/2014-March/001821.html[deprecated],
|
||||
these bugs are never going to be fixed.
|
||||
+
|
||||
The newer http://webkitgtk.org/reference/webkit2gtk/stable/index.html[WebKit2
|
||||
API] seems to lack basic features like proxy support, and almost no projects
|
||||
seem to have started porting to WebKit2 (I only know of
|
||||
http://www.uzbl.org/[uzbl]).
|
||||
+
|
||||
qutebrowser uses http://qt-project.org/[Qt] and
|
||||
http://qt-project.org/wiki/QtWebKit[QtWebKit] instead, which suffers from far
|
||||
less such crashes. It might switch to
|
||||
http://qt-project.org/wiki/QtWebEngine[QtWebEngine] in the future, which is
|
||||
based on Google's https://en.wikipedia.org/wiki/Blink_(layout_engine)[Blink]
|
||||
rendering engine.
|
||||
|
||||
What's wrong with https://www.mozilla.org/en-US/firefox/new/[Firefox] and link:http://5digits.org/pentadactyl/[Pentadactyl]/link:http://www.vimperator.org/vimperator[Vimperator]?::
|
||||
Firefox likes to break compatibility with addons on each upgrade, gets
|
||||
slower and more bloated with every upgrade, and has some
|
||||
https://blog.mozilla.org/advancingcontent/2014/02/11/publisher-transformation-with-users-at-the-center/[horrible
|
||||
ideas] lately.
|
||||
+
|
||||
Also, developing addons for it is a nightmare.
|
||||
|
||||
What's wrong with http://www.chromium.org/Home[Chromium] and https://vimium.github.io/[Vimium]?::
|
||||
The Chrome plugin API doesn't seem to allow much freedom for plugin
|
||||
writers, which results in Vimium not really having all the features you'd
|
||||
expect from a proper minimal, vim-like browser.
|
||||
|
||||
Why Python?::
|
||||
I enjoy writing Python since 2011, which made it one of the possible
|
||||
choices. I wanted to use http://qt-project.org/[Qt] because of
|
||||
http://qt-project.org/wiki/QtWebKit[QtWebKit] so I didn't have
|
||||
http://qt-project.org/wiki/Category:LanguageBindings[many other choices]. I
|
||||
don't like C++ and can't write it very well, so that wasn't an alternative.
|
||||
|
||||
But isn't Python too slow for a browser?::
|
||||
http://www.infoworld.com/d/application-development/van-rossum-python-not-too-slow-188715[No.]
|
||||
I believe efficency while coding is a lot more important than efficency
|
||||
while running. Also, most of the heavy lifting of qutebrowser is done by Qt
|
||||
and WebKit in C++, with the
|
||||
https://wiki.python.org/moin/GlobalInterpreterLock[GIL] released.
|
||||
|
||||
Is there an adblocker?::
|
||||
There is a host-based adblocker which takes /etc/hosts-like lists. A "real"
|
||||
adblocker has a
|
||||
http://www.reddit.com/r/programming/comments/25j41u/adblock_pluss_effect_on_firefoxs_memory_usage/chhpomw[big
|
||||
impact] on browsing speed and
|
||||
https://blog.mozilla.org/nnethercote/2014/05/14/adblock-pluss-effect-on-firefoxs-memory-usage/[RAM
|
||||
usage], so implementing it properly might take some time and won't be done
|
||||
for v0.1 if at all.
|
||||
|
||||
== Troubleshooting
|
||||
|
||||
Configuration not saved after modifying config.::
|
||||
When editing your config file manually, qutebrowser must be exited completely.
|
||||
This can be done by issuing the command `:quit` or by pressing `Ctrl+q`.
|
||||
|
||||
Unable to view flash content.::
|
||||
If you have flash installed for on your system, it's necessary to enable plugins
|
||||
to use the flash plugin. Using the command `:set content allow-plugins true`
|
||||
in qutebrowser will enable plugins. Packages for flash should
|
||||
be provided for your platform or it can be obtained from
|
||||
http://get.adobe.com/flashplayer/[Adobe].
|
||||
|
||||
Experiencing freezing on sites like duckduckgo and youtube.::
|
||||
This issue could be caused by stale plugin files installed by `mozplugger`
|
||||
if mozplugger was subsequently removed.
|
||||
Try exiting qutebroser and removing `~/.mozilla/plugins/mozplugger*.so`.
|
||||
See https://github.com/The-Compiler/qutebrowser/issues/357[Issue #357]
|
||||
for more details.
|
||||
|
||||
Experiencing segfaults (crashes) on Debian systems.::
|
||||
For Debian it's highly recommended to install the `gstreamer0.10-plugins-base` package.
|
||||
This is a workaround for a bug in Qt, it has been fixed upstream in Qt 5.4
|
||||
More details can be found
|
||||
https://bugs.webkit.org/show_bug.cgi?id=119951[here].
|
||||
|
||||
Segfaults on Facebook, Medium, Amazon, ...::
|
||||
If you are on a Debian or Ubuntu based system, you might experience some crashes
|
||||
visting these sites. This is caused by a known bug in Qt which has been
|
||||
fixed in Qt 5.4. However Debian and Ubuntu are slow to adopt or upgrade
|
||||
some packages. There is currently no easy way to manually upgrade to Qt
|
||||
5.4 on those systems.
|
||||
|
||||
My issue is not listed.::
|
||||
If you experience any segfaults or crashes, you can report the issue in
|
||||
https://github.com/The-Compiler/qutebrowser/issues[the issue tracker] or
|
||||
using the `:report` command.
|
||||
If you are reporting a segfault, make sure you read the
|
||||
https://github.com/The-Compiler/qutebrowser/blob/master/doc/stacktrace.asciidoc[guide]
|
||||
on how to report them with all needed information.
|
||||
@@ -1,5 +1,5 @@
|
||||
Contributing to qutebrowser
|
||||
===========================
|
||||
qutebrowser HACKING
|
||||
===================
|
||||
The Compiler <mail@qutebrowser.org>
|
||||
:icons:
|
||||
:data-uri:
|
||||
@@ -11,9 +11,9 @@ This document contains guidelines for contributing to qutebrowser, as well as
|
||||
useful hints when doing so.
|
||||
|
||||
If anything mentioned here would prevent you from contributing, please let me
|
||||
know, and contribute anyways! The guidelines are meant to make life easier for
|
||||
me, but if you don't follow everything in here, I won't be mad at you. In
|
||||
fact, I will probably change it for you.
|
||||
know, and contribute anyways! The guidelines are only meant to make life easier
|
||||
for me, but if you don't follow anything in here, I won't be mad at you. I will
|
||||
probably change it for you then, though.
|
||||
|
||||
If you have any problems, I'm more than happy to help! You can get help in
|
||||
several ways:
|
||||
@@ -34,22 +34,19 @@ this. It might be a good idea to ask on the mailing list or IRC channel to make
|
||||
sure nobody else started working on the same thing already.
|
||||
|
||||
If you want to find something useful to do, check the
|
||||
https://github.com/qutebrowser/qutebrowser/issues[issue tracker]. Some
|
||||
https://github.com/The-Compiler/qutebrowser/issues[issue tracker]. Some
|
||||
pointers:
|
||||
|
||||
* https://github.com/qutebrowser/qutebrowser/labels/easy[Issues which should
|
||||
* https://github.com/The-Compiler/qutebrowser/milestones/v0.1[Open issues for
|
||||
the v0.1 release]
|
||||
* https://github.com/The-Compiler/qutebrowser/labels/easy[Issues which should
|
||||
be easy to solve]
|
||||
* https://github.com/qutebrowser/qutebrowser/labels/component%3A%20docs[Documentation issues which require little/no coding]
|
||||
|
||||
If you prefer C++ or Javascript to Python, see the relevant issues which involve
|
||||
work in those languages:
|
||||
|
||||
* https://github.com/qutebrowser/qutebrowser/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3Ac%2B%2B[C++] (mostly work on Qt, the library behind qutebrowser)
|
||||
* https://github.com/qutebrowser/qutebrowser/issues?q=is%3Aopen+is%3Aissue+label%3Ajavascript[JavaScript]
|
||||
* https://github.com/The-Compiler/qutebrowser/labels/not%20code[Issues which
|
||||
require little/no coding]
|
||||
|
||||
There are also some things to do if you don't want to write code:
|
||||
|
||||
* Help the community, e.g., on the mailinglist and the IRC channel.
|
||||
* Help the community, e.g. on the mailinglist and the IRC channel.
|
||||
* Improve the documentation.
|
||||
* Help on the website and graphics (logo, etc.).
|
||||
|
||||
@@ -60,29 +57,24 @@ qutebrowser uses http://git-scm.com/[git] for its development. You can clone
|
||||
the repo like this:
|
||||
|
||||
----
|
||||
git clone https://github.com/qutebrowser/qutebrowser.git
|
||||
git clone git://the-compiler.org/qutebrowser
|
||||
----
|
||||
|
||||
If you don't know git, a http://git-scm.com/[git cheatsheet] might come in
|
||||
handy. Of course, if using git is the issue which prevents you from
|
||||
contributing, feel free to send normal patches instead, e.g., generated via
|
||||
contributing, feel free to send normal patches instead, e.g. generated via
|
||||
`diff -Nur`.
|
||||
|
||||
Getting patches
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
The preferred way of submitting changes is to
|
||||
https://help.github.com/articles/fork-a-repo/[fork the repository] and to
|
||||
https://help.github.com/articles/creating-a-pull-request/[submit a pull
|
||||
request].
|
||||
|
||||
If you prefer to send a patch to the mailinglist, you can generate a patch
|
||||
based on your changes like this:
|
||||
After you finished your work and did `git commit`, you can get patches of your
|
||||
changes like this:
|
||||
|
||||
----
|
||||
git format-patch origin/master <1>
|
||||
----
|
||||
<1> Replace `master` by the branch your work was based on, e.g.,
|
||||
<1> Replace `master` by the branch your work was based on, e.g.
|
||||
`origin/develop`.
|
||||
|
||||
Useful utilities
|
||||
@@ -91,48 +83,37 @@ Useful utilities
|
||||
Checkers
|
||||
~~~~~~~~
|
||||
|
||||
qutebrowser uses http://tox.readthedocs.org/en/latest/[tox] to run its
|
||||
unittests and several linters/checkers.
|
||||
In the _scripts/_ subfolder, there is a `run_checks.py` script.
|
||||
|
||||
Currently, the following tox environments are available:
|
||||
It runs a bunch of static checks on all source files, using the following
|
||||
checkers:
|
||||
|
||||
* Tests using https://www.pytest.org[pytest]:
|
||||
- `py35`, `py36`: Run pytest for python 3.5/3.6 with the system-wide PyQt.
|
||||
- `py36-pyqt57`, ..., `py36-pyqt59`: Run pytest with the given PyQt version (`py35-*` also works).
|
||||
- `py36-pyqt59-cov`: Run with coverage support (other Python/PyQt versions work too).
|
||||
* `flake8`: Run https://pypi.python.org/pypi/flake8[flake8] checks:
|
||||
https://pypi.python.org/pypi/pyflakes[pyflakes],
|
||||
https://pypi.python.org/pypi/pep8[pep8],
|
||||
https://pypi.python.org/pypi/mccabe[mccabe].
|
||||
* `vulture`: Run https://pypi.python.org/pypi/vulture[vulture] to find
|
||||
unused code portions.
|
||||
* `pylint`: Run http://pylint.org/[pylint] static code analysis.
|
||||
* `pydocstyle`: Check
|
||||
https://www.python.org/dev/peps/pep-0257/[PEP257] compliance with
|
||||
https://github.com/PyCQA/pydocstyle[pydocstyle].
|
||||
* `pyroma`: Check packaging practices with
|
||||
https://pypi.python.org/pypi/pyroma/[pyroma].
|
||||
* `eslint`: Run http://eslint.org/[ESLint] javascript checker.
|
||||
* `check-manifest`: Check MANIFEST.in completeness with
|
||||
https://github.com/mgedmin/check-manifest[check-manifest].
|
||||
* `mkvenv`: Bootstrap a virtualenv for testing.
|
||||
* `misc`: Run `scripts/misc_checks.py` to check for:
|
||||
* Unit tests using the Python
|
||||
https://docs.python.org/3.4/library/unittest.html[unittest] framework
|
||||
* https://pypi.python.org/pypi/flake8/1.3.1[flake8]
|
||||
* https://github.com/GreenSteam/pep257/[pep257]
|
||||
* http://pylint.org/[pylint]
|
||||
* A custom checker for the following things:
|
||||
- untracked git files
|
||||
- VCS conflict markers
|
||||
- common spelling mistakes
|
||||
|
||||
The default test suite is run with `tox`; the list of default
|
||||
environments is obtained with `tox -l`.
|
||||
If you changed `setup.py` or `MANIFEST.in`, add the `--setup` argument to run
|
||||
the following additional checkers:
|
||||
|
||||
Please make sure the checks run without any warnings on your new contributions.
|
||||
* https://pypi.python.org/pypi/pyroma/0.9.3[pyroma]
|
||||
* https://github.com/mgedmin/check-manifest[check-manifest]
|
||||
|
||||
There's always the possibility of false positives; the following
|
||||
techniques are useful to handle these:
|
||||
It needs all the checkers to be installed and also needs
|
||||
https://pypi.python.org/pypi/colorama/[colorama].
|
||||
|
||||
Please make sure this script runs without any warnings on your new
|
||||
contributions. There's of course the possibility of false-positives, and the
|
||||
following techniques are useful to handle these:
|
||||
|
||||
* Use `_foo` for unused parameters, with `foo` being a descriptive name. Using
|
||||
`_` is discouraged.
|
||||
* If you think you have a good reason to suppress a message, then add the
|
||||
following comment:
|
||||
* If you think you have a good reason to suppress a message, add the following
|
||||
comment:
|
||||
+
|
||||
----
|
||||
# pylint: disable=message-name
|
||||
@@ -144,56 +125,24 @@ smallest scope which makes sense. Most of the time, this will be line scope.
|
||||
* If you really think a check shouldn't be done globally as it yields a lot of
|
||||
false-positives, let me know! I'm still tweaking the parameters.
|
||||
|
||||
|
||||
Running Specific Tests
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
While you are developing you often don't want to run the full test
|
||||
suite each time.
|
||||
|
||||
Specific test environments can be run with `tox -e <envlist>`.
|
||||
|
||||
Additional parameters can be passed to the test scripts by separating
|
||||
them from `tox` arguments with `--`.
|
||||
|
||||
Examples:
|
||||
|
||||
----
|
||||
# run only pytest tests which failed in last run:
|
||||
tox -e py35 -- --lf
|
||||
|
||||
# run only the end2end feature tests:
|
||||
tox -e py35 -- tests/end2end/features
|
||||
|
||||
# run everything with undo in the generated name, based on the scenario text
|
||||
tox -e py35 -- tests/end2end/features/test_tabs_bdd.py -k undo
|
||||
|
||||
# run coverage test for specific file (updates htmlcov/index.html)
|
||||
tox -e py35-cov -- tests/unit/browser/test_webelem.py
|
||||
----
|
||||
|
||||
Profiling
|
||||
~~~~~~~~~
|
||||
|
||||
In the _scripts/_ subfolder there's a `run_profile.py` which profiles the code
|
||||
and shows a graphical representation of what takes how much time.
|
||||
|
||||
It uses the built-in Python
|
||||
https://docs.python.org/3.6/library/profile.html[cProfile] module and can show
|
||||
the output in four different ways:
|
||||
|
||||
* Raw profile file (`--profile-tool=none`)
|
||||
* https://pypi.python.org/pypi/pyprof2calltree/[pyprof2calltree] and http://kcachegrind.sourceforge.net/html/Home.html[KCacheGrind] (`--profile-tool=kcachegrind`)
|
||||
* https://jiffyclub.github.io/snakeviz/[SnakeViz] (`--profile-tool=snakeviz`)
|
||||
* https://github.com/jrfonseca/gprof2dot[gprof2dot] (needs `dot` from http://graphviz.org/[Graphviz] and http://feh.finalrewind.org/[feh])
|
||||
It needs https://pypi.python.org/pypi/pyprof2calltree/[pyprof2calltree] and
|
||||
http://kcachegrind.sourceforge.net/html/Home.html[KCacheGrind]. It uses the
|
||||
built-in Python https://docs.python.org/3.4/library/profile.html[cProfile]
|
||||
module.
|
||||
|
||||
Debugging
|
||||
~~~~~~~~~
|
||||
|
||||
There are some useful functions for debugging in the `qutebrowser.utils.debug`
|
||||
module.
|
||||
In the `qutebrowser.utils.debug` module there are some useful functions for
|
||||
debugging.
|
||||
|
||||
When starting qutebrowser with the `--debug` flag, you also get useful debug
|
||||
When starting qutebrowser with the `--debug` flag you also get useful debug
|
||||
logs. You can add +--logfilter _category[,category,...]_+ to restrict logging
|
||||
to the given categories.
|
||||
|
||||
@@ -207,7 +156,7 @@ Useful websites
|
||||
|
||||
Some resources which might be handy:
|
||||
|
||||
* http://doc.qt.io/qt-5/classes.html[The Qt5 reference]
|
||||
* http://qt-project.org/doc/qt-5/classes.html[The Qt5 reference]
|
||||
* https://docs.python.org/3/library/index.html[The Python reference]
|
||||
* http://httpbin.org/[httpbin, a test service for HTTP requests/responses]
|
||||
* http://requestb.in/[RequestBin, a service to inspect HTTP requests]
|
||||
@@ -218,8 +167,9 @@ Documentation of used Python libraries:
|
||||
* http://pygments.org/docs/[pygments]
|
||||
* http://fdik.org/pyPEG/index.html[pyPEG2]
|
||||
* http://pythonhosted.org/setuptools/[setuptools]
|
||||
* http://www.pyinstaller.org/[PyInstaller]
|
||||
* http://cx-freeze.readthedocs.org/en/latest/overview.html[cx_Freeze]
|
||||
* https://pypi.python.org/pypi/colorama[colorama]
|
||||
* https://pypi.python.org/pypi/colorlog[colorlog]
|
||||
|
||||
Related RFCs and standards:
|
||||
|
||||
@@ -264,7 +214,8 @@ Other
|
||||
Languages] (http://www.rfc-editor.org/errata_search.php?rfc=5646[Errata])
|
||||
* http://www.w3.org/TR/CSS2/[Cascading Style Sheets Level 2 Revision 1 (CSS
|
||||
2.1) Specification]
|
||||
* http://doc.qt.io/qt-5/stylesheet-reference.html[Qt Style Sheets Reference]
|
||||
* http://qt-project.org/doc/qt-4.8/stylesheet-reference.html[Qt Style Sheets
|
||||
Reference]
|
||||
* http://mimesniff.spec.whatwg.org/[MIME Sniffing Standard]
|
||||
* http://spec.whatwg.org/[WHATWG specifications]
|
||||
* http://www.w3.org/html/wg/drafts/html/master/Overview.html[HTML 5.1 Nightly]
|
||||
@@ -280,40 +231,43 @@ Hints
|
||||
Python and Qt objects
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For many tasks, there are solutions available in both Qt and the Python
|
||||
standard library.
|
||||
For many tasks, there are solutions in both Qt and the Python standard libary
|
||||
available.
|
||||
|
||||
In qutebrowser, the policy is usually to use the Python libraries, as they
|
||||
In qutebrowser, the policy is usually using the Python libraries, as they
|
||||
provide exceptions and other benefits.
|
||||
|
||||
There are some exceptions to that:
|
||||
|
||||
* `QThread` is used instead of Python threads because it provides signals and
|
||||
slots.
|
||||
* `QProcess` is used instead of Python's `subprocess`.
|
||||
* `QProcess` is used instead of Python's `subprocess` if certain actions (e.g.
|
||||
cleanup) when the process finished are desired, as it provides signals for
|
||||
that.
|
||||
* `QUrl` is used instead of storing URLs as string, see the
|
||||
<<handling-urls,handling URLs>> section for details.
|
||||
|
||||
When using Qt objects, two issues must be taken care of:
|
||||
|
||||
* Methods of Qt objects report their status with their return values,
|
||||
* Methods of Qt objects report their status by using their return values,
|
||||
instead of using exceptions.
|
||||
+
|
||||
If a function gets or returns a Qt object which has an `.isValid()`
|
||||
method such as `QUrl` or `QModelIndex`, there's a helper function
|
||||
`ensure_valid` in `qutebrowser.utils.qtutils` which should get called
|
||||
on all such objects. It will raise
|
||||
`qutebrowser.utils.qtutils.QtValueError` if the value is not valid.
|
||||
If a function gets or returns a Qt object which
|
||||
has an `.isValid()` method such as `QUrl` or `QModelIndex`, there's a helper
|
||||
function `ensure_valid` in `qutebrowser.utils.qt` which should get called on
|
||||
all such objects. It will raise `qutebrowser.utils.qt.QtValueError` if the
|
||||
value is not valid.
|
||||
+
|
||||
If a function returns something else on error, the return value should
|
||||
carefully be checked.
|
||||
|
||||
* Methods of Qt objects have certain maximum values based on their
|
||||
underlying C++ types.
|
||||
* Methods of Qt objects have certain maximum values, based on their underlying
|
||||
C++ types.
|
||||
+
|
||||
To avoid passing too large of a numeric parameter to a Qt function, all
|
||||
numbers should be range-checked using `qutebrowser.qtutils.check_overflow`,
|
||||
or by other means (e.g. by setting a maximum value for a config object).
|
||||
When passing a numeric parameter to a Qt function, all numbers should be
|
||||
range-checked using `qutebrowser.utils.check_overflow`, or passing a value
|
||||
which is too large should be avoided by other means (e.g. by setting a maximum
|
||||
value for a config object).
|
||||
|
||||
[[object-registry]]
|
||||
The object registry
|
||||
@@ -325,10 +279,10 @@ dictionaries which map object names to the actual long-living objects.
|
||||
There are currently these object registries, also called 'scopes':
|
||||
|
||||
* The `global` scope, with objects which are used globally (`config`,
|
||||
`cookie-jar`, etc.).
|
||||
`cookie-jar`, etc.)
|
||||
* The `tab` scope with objects which are per-tab (`hintmanager`, `webview`,
|
||||
etc.). Passing this scope to `objreg.get()` selects the object in the currently
|
||||
focused tab by default. A tab can be explicitly selected by passing
|
||||
focused tab by default. A tab can be explicitely selected by passing
|
||||
+tab=_tab-id_, window=_win-id_+ to it.
|
||||
|
||||
A new object can be registered by using
|
||||
@@ -342,10 +296,10 @@ window=_win-id_, tab=_tab-id_])+. The default scope is `global`.
|
||||
All objects can be printed by starting with the `--debug` flag and using the
|
||||
`:debug-all-objects` command.
|
||||
|
||||
The registry is mainly used for <<commands,command handlers>>, but it can
|
||||
also be useful in places where using Qt's
|
||||
http://doc.qt.io/qt-5/signalsandslots.html[signals and slots] mechanism would
|
||||
be difficult.
|
||||
The registry is mainly used for <<commands,command handlers>> but also can be
|
||||
useful in places where using Qt's
|
||||
http://qt-project.org/doc/qt-5/signalsandslots.html[signals and slots]
|
||||
mechanism would be difficult.
|
||||
|
||||
Logging
|
||||
~~~~~~~
|
||||
@@ -353,7 +307,7 @@ Logging
|
||||
Logging is used at various places throughout the qutebrowser code. If you add a
|
||||
new feature, you should also add some strategic debug logging.
|
||||
|
||||
Unlike other Python projects, qutebrowser doesn't use a logger per file,
|
||||
Unless other Python projects, qutebrowser doesn't use a logger per file,
|
||||
instead it uses custom-named loggers.
|
||||
|
||||
The existing loggers are defined in `qutebrowser.utils.log`. If your feature
|
||||
@@ -377,7 +331,7 @@ The following logging levels are available for every logger:
|
||||
|
||||
[width="75%",cols="25%,75%"]
|
||||
|=======================================================================
|
||||
|critical |Critical issue, qutebrowser can't continue to run.
|
||||
|criticial |Critical issue, qutebrowser can't continue to run.
|
||||
|error |There was an issue and some kind of operation was abandoned.
|
||||
|warning |There was an issue but the operation can continue running.
|
||||
|info |General informational messages.
|
||||
@@ -415,68 +369,44 @@ then gets passed as the `self` parameter to the handler. The `scope` argument
|
||||
selects which object registry (global, per-tab, etc.) to use. See the
|
||||
<<object-registry,object registry>> section for details.
|
||||
|
||||
There are also other arguments to customize the way the command is
|
||||
registered; see the class documentation for `register` in
|
||||
`qutebrowser.commands.cmdutils` for details.
|
||||
There are also other arguments to customize the way the command is registered,
|
||||
see the class documentation for `register` in `qutebrowser.commands.utils` for
|
||||
details.
|
||||
|
||||
The types of the function arguments are inferred based on their default values,
|
||||
e.g., an argument `foo=True` will be converted to a flag `-f`/`--foo` in
|
||||
e.g. an argument `foo=True` will be converted to a flag `-f`/`--foo` in
|
||||
qutebrowser's commandline.
|
||||
|
||||
The type can be overridden using Python's
|
||||
http://legacy.python.org/dev/peps/pep-3107/[function annotations]:
|
||||
This behaviour can be overridden using Python's
|
||||
http://legacy.python.org/dev/peps/pep-3107/[function annotations]. The
|
||||
annotation should always be a `dict`, like this:
|
||||
|
||||
[source,python]
|
||||
----
|
||||
@cmdutils.register(...)
|
||||
def foo(bar: int, baz=True):
|
||||
def foo(bar: {'type': int}, baz=True):
|
||||
...
|
||||
----
|
||||
|
||||
Possible values:
|
||||
The following keys are supported in the dict:
|
||||
|
||||
- A callable (`int`, `float`, etc.): Gets called to validate/convert the value.
|
||||
- A python enum type: All members of the enum are possible values.
|
||||
- A `typing.Union` of multiple types above: Any of these types are valid
|
||||
values, e.g., `typing.Union[str, int]`.
|
||||
|
||||
You can customize how an argument is handled using the `@cmdutils.argument`
|
||||
decorator *after* `@cmdutils.register`. This can, for example, be used to
|
||||
customize the flag an argument should get:
|
||||
|
||||
[source,python]
|
||||
----
|
||||
@cmdutils.register(...)
|
||||
@cmdutils.argument('bar', flag='c')
|
||||
def foo(bar):
|
||||
...
|
||||
----
|
||||
|
||||
For a `str` argument, you can restrict the allowed strings using `choices`:
|
||||
|
||||
[source,python]
|
||||
----
|
||||
@cmdutils.register(...)
|
||||
@cmdutils.argument('bar', choices=['val1', 'val2'])
|
||||
def foo(bar: str):
|
||||
...
|
||||
----
|
||||
|
||||
For `typing.Union` types, the given `choices` are only checked if other types
|
||||
(like `int`) don't match.
|
||||
|
||||
The following arguments are supported for `@cmdutils.argument`:
|
||||
|
||||
- `flag`: Customize the short flag (`-x`) the argument will get.
|
||||
- `win_id=True`: Mark the argument as special window ID argument.
|
||||
- `count=True`: Mark the argument as special count argument.
|
||||
- `hide=True`: Hide the argument from the documentation.
|
||||
- `completion`: A completion function (see `qutebrowser.completions.models.*`)
|
||||
to use when completing arguments for the given command.
|
||||
- `choices`: The allowed string choices for the argument.
|
||||
|
||||
The name of an argument will always be the parameter name, with any trailing
|
||||
underscores stripped and underscores replaced by dashes.
|
||||
* `type`: The type this value should have. The value entered by the user is
|
||||
then automatically checked. Possible values:
|
||||
- A callable (`int`, `float`, etc.): Gets called to validate/convert the
|
||||
value.
|
||||
- A string: The value must match exactly (mainly useful with tuples to get
|
||||
a choice of values, see below).
|
||||
- A python enum type: All members of the enum are possible values.
|
||||
- A tuple of multiple types above: Any of these types are valid values,
|
||||
e.g. `('foo', 'bar')` or `(int, 'foo')`.
|
||||
* `flag`: The flag to be used, as 1-char string (default: First char of the
|
||||
long name).
|
||||
* `name`: The long name to be used, as string (default: Name of the parameter).
|
||||
* `special`: The string `count` or `win_id` if the parameter should be
|
||||
auto-filled (with the count given by the user and the window ID the command was
|
||||
executed in, respectively).
|
||||
* `nargs`: Gets passed to argparse, see
|
||||
https://docs.python.org/dev/library/argparse.html#nargs[its documentation].
|
||||
|
||||
[[handling-urls]]
|
||||
Handling URLs
|
||||
@@ -486,13 +416,13 @@ qutebrowser handles two different types of URLs: URLs as a string, and URLs as
|
||||
the Qt `QUrl` type. As this can get confusing quickly, please follow the
|
||||
following guidelines:
|
||||
|
||||
* Convert a string to a QUrl object as early as possible, i.e., directly after
|
||||
* Convert a string to a QUrl object as early as possible, i.e. directly after
|
||||
the user did enter it.
|
||||
- Use `utils.urlutils.fuzzy_url` if the URL is entered by the user
|
||||
somewhere.
|
||||
- Be sure you handle `utils.urlutils.FuzzyError` and display an error
|
||||
message to the user.
|
||||
* Convert a `QUrl` object to a string as late as possible, i.e., before
|
||||
* Convert a `QUrl` object to a string as late as possible, e.g. before
|
||||
displaying it to the user.
|
||||
- If you want to display the URL to the user, use `url.toDisplayString()`
|
||||
so password information is removed.
|
||||
@@ -506,73 +436,6 @@ displaying it to the user.
|
||||
`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).
|
||||
|
||||
Running valgrind on QtWebKit
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want to run qutebrowser (and thus QtWebKit) with
|
||||
http://valgrind.org/[valgrind], you'll need to pass `--smc-check=all` to it or
|
||||
recompile QtWebKit with the Javascript JIT disabled.
|
||||
|
||||
This is needed so valgrind handles self-modifying code correctly:
|
||||
|
||||
[quote]
|
||||
____
|
||||
This option controls Valgrind's detection of self-modifying code. If no
|
||||
checking is done and a program executes some code, overwrites it with new
|
||||
code, and then executes the new code, Valgrind will continue to execute the
|
||||
translations it made for the old code. This will likely lead to incorrect
|
||||
behavior and/or crashes.
|
||||
|
||||
...
|
||||
|
||||
Note that the default option will catch the vast majority of cases. The main
|
||||
case it will not catch is programs such as JIT compilers that dynamically
|
||||
generate code and subsequently overwrite part or all of it. Running with all
|
||||
will slow Valgrind down noticeably.
|
||||
____
|
||||
|
||||
Setting up a Windows Development Environment
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Install https://www.python.org/downloads/release/python-362/[Python 3.6].
|
||||
* Install PyQt via `pip install PyQt5`.
|
||||
* Create a file at `C:\Windows\system32\python3.bat` with the following content (adjust the path as necessary):
|
||||
`@C:\Python36\python %*`.
|
||||
This will make the Python 3.6 interpreter available as `python3`, which is used by various development scripts.
|
||||
* Install git from the https://git-scm.com/download/win[git-scm downloads page].
|
||||
Try not to enable `core.autocrlf`, since that will cause `flake8` to complain a lot. Use an editor that can deal with plain line feeds instead.
|
||||
* Clone your favourite qutebrowser repository.
|
||||
* To install tox, open an elevated cmd, enter your working directory and run `pip install -rmisc/requirements/requirements-tox.txt`.
|
||||
|
||||
Note that the `flake8` tox env might not run due to encoding errors despite having LANG/LC_* set correctly.
|
||||
|
||||
Rebuilding the website
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want to rebuild the website, run `./scripts/asciidoc2html.py --website <outputdir>`.
|
||||
|
||||
Chrome URLs
|
||||
~~~~~~~~~~~
|
||||
|
||||
With the QtWebEngine backend, qutebrowser supports several chrome:// urls which
|
||||
can be useful for debugging:
|
||||
|
||||
- chrome://appcache-internals/
|
||||
- chrome://blob-internals/
|
||||
- chrome://gpu/
|
||||
- chrome://histograms/
|
||||
- chrome://indexeddb-internals/
|
||||
- chrome://media-internals/
|
||||
- chrome://network-errors/
|
||||
- chrome://serviceworker-internals/
|
||||
- chrome://webrtc-internals/
|
||||
- chrome://crash/ (crashes the current renderer process!)
|
||||
- chrome://kill/ (kills the current renderer process!)
|
||||
- chrome://gpucrash/ (crashes qutebrowser!)
|
||||
- chrome://gpuhang/ (hangs qutebrowser!)
|
||||
- chrome://gpuclean/ (crashes the current renderer process!)
|
||||
- chrome://ppapiflashcrash/
|
||||
- chrome://ppapiflashhang/
|
||||
|
||||
Style conventions
|
||||
-----------------
|
||||
@@ -642,7 +505,10 @@ Return:
|
||||
* The layout of a class should be like this:
|
||||
- docstring
|
||||
- `__magic__` methods
|
||||
- other methods
|
||||
- properties
|
||||
- _private methods
|
||||
- public methods
|
||||
- `on_*` methods
|
||||
- overrides of Qt methods
|
||||
|
||||
Checklists
|
||||
@@ -655,45 +521,42 @@ New Qt release
|
||||
|
||||
* Run all tests and check nothing is broken.
|
||||
* Check the
|
||||
https://bugreports.qt.io/issues/?jql=reporter%20%3D%20%22The%20Compiler%22%20ORDER%20BY%20fixVersion%20ASC[Qt bugtracker]
|
||||
https://bugreports.qt-project.org/issues/?jql=reporter%20%3D%20%22The%20Compiler%22%20ORDER%20BY%20fixVersion%20ASC[Qt bugtracker]
|
||||
and make sure all bugs marked as resolved are actually fixed.
|
||||
* Update own PKGBUILDs based on upstream Archlinux updates and rebuild.
|
||||
* Update recommended Qt version in `README`.
|
||||
* Update own PKGBUILDs based on upstream Archlinux updates.
|
||||
* Build developer packages.
|
||||
* Build non-developer symbol packages.
|
||||
* Upload symbols patch to http://www.qutebrowser.org/qt-symbols.patch
|
||||
* Upload symbols packages to http://www.qutebrowser.org/qt-symbols-pkg/
|
||||
* Update recommended Qt version in `README`
|
||||
* Update OS X instructions in `README`
|
||||
* Make sure Gentoo instructions are up to date.
|
||||
* Grep for `WORKAROUND` in the code and test if fixed stuff works without the
|
||||
workaround.
|
||||
* Check relevant
|
||||
https://github.com/qutebrowser/qutebrowser/issues?q=is%3Aopen+is%3Aissue+label%3Aqt[qutebrowser
|
||||
bugs] and check if they're fixed.
|
||||
|
||||
New PyQt release
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
* See above.
|
||||
* Install new PyQt in Windows VM (32- and 64-bit).
|
||||
* Download new installer and update PyQt installer path in `ci_install.py`.
|
||||
* Update `tox.ini`/`.travis.yml`/`.appveyor.yml` to test new versions.
|
||||
|
||||
qutebrowser release
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Make sure there are no unstaged changes and the tests are green.
|
||||
* Run `x=... y=...` to set the respective shell variables.
|
||||
|
||||
* Make sure there are no unstaged changes.
|
||||
* Run `src2asciidoc.py` and commit changes if necessary.
|
||||
* Run `asciidoc2html.py`.
|
||||
* Adjust `__version_info__` in `qutebrowser/__init__.py`.
|
||||
* Update changelog (remove *(unreleased)*).
|
||||
* Run tests again.
|
||||
* Commit.
|
||||
|
||||
* Create annotated git tag (`git tag -s "v1.$x.$y" -m "Release v1.$x.$y"`).
|
||||
* `git push origin`; `git push origin v1.$x.$y`.
|
||||
* If committing on minor branch, cherry-pick release commit to master.
|
||||
* Create release on github.
|
||||
* Mark the milestone at https://github.com/qutebrowser/qutebrowser/milestones
|
||||
* Run all tests on all supported systems.
|
||||
* Test an upgrade from the previous version (no manual intervention).
|
||||
* Test an upgrade from the first version (no manual intervention).
|
||||
|
||||
* Create annotated git tag (`git tag -s "v0.1" -m "Release v0.1"`)
|
||||
* Create git branch `v0.1.x`
|
||||
* Push including `--tags`
|
||||
* Create release on github
|
||||
* Mark the milestone at https://github.com/The-Compiler/qutebrowser/milestones
|
||||
as closed.
|
||||
|
||||
* Linux: Run `python3 scripts/dev/build_release.py --upload v1.$x.$y`.
|
||||
* Windows: Run `C:\Python36-32\python scripts\dev\build_release.py --asciidoc C:\Python27\python C:\asciidoc-8.6.9\asciidoc.py --upload v1.X.Y` (replace X/Y by hand).
|
||||
* macOS: Run `python3 scripts/dev/build_release.py --upload v1.X.Y` (replace X/Y by hand).
|
||||
* On server: Run `python3 scripts/dev/download_release.py v1.X.Y` (replace X/Y by hand).
|
||||
* Update `qutebrowser-git` PKGBUILD if dependencies/install changed.
|
||||
* Announce to qutebrowser and qutebrowser-announce mailinglist.
|
||||
* Create standalone Windows package (32/64bit) in Windows VM
|
||||
* Upload to PyPI: `python setup.py register sdist upload --sign`
|
||||
* Maybe upload to http://qt-apps.org/
|
||||
* Upload to webpage with checksum/GPG (when/if it exists)
|
||||
|
||||
* Announce to qutebrowser mailinglist
|
||||
* Maybe annouce at other places?
|
||||
142
doc/INSTALL.asciidoc
Normal file
@@ -0,0 +1,142 @@
|
||||
Installing qutebrowser
|
||||
======================
|
||||
|
||||
On Debian / Ubuntu
|
||||
------------------
|
||||
|
||||
qutebrowser should run on these systems:
|
||||
|
||||
* Debian jessie or newer
|
||||
* Ubuntu Trusty (14.04 LTS) or newer
|
||||
* Any other distribution based on these (e.g. Linux Mint)
|
||||
|
||||
Install the dependencies via apt-get:
|
||||
|
||||
----
|
||||
# apt-get install python3-pyqt5 python3-pyqt5.qtwebkit python-virtualenv
|
||||
----
|
||||
|
||||
To generate the documentation for the `:help` command, when using the git
|
||||
repository (rather than a release):
|
||||
|
||||
----
|
||||
# apt-get install asciidoc
|
||||
# python3 scripts/asciidoc2html.py
|
||||
----
|
||||
|
||||
Then run the supplied script to run qutebrowser inside a
|
||||
https://virtualenv.pypa.io/en/latest/virtualenv.html[virtualenv]:
|
||||
|
||||
----
|
||||
# python3 scripts/init_venv.py
|
||||
----
|
||||
|
||||
This installs all needed Python dependencies in a `.venv` subfolder. The
|
||||
system-wide Qt5/PyQt5 installations are symlinked into the virtualenv.
|
||||
|
||||
You can then create a simple wrapper script to start qutebrowser somewhere in
|
||||
your `$PATH` (e.g. `/usr/local/bin/qutebrowser` or `~/bin/qutebrowser`):
|
||||
|
||||
----
|
||||
#!/bin/bash
|
||||
~/path/to/qutebrowser/.venv/bin/python3 -m qutebrowser
|
||||
----
|
||||
|
||||
On Archlinux
|
||||
------------
|
||||
|
||||
There are two Archlinux packages available in the AUR:
|
||||
https://aur.archlinux.org/packages/qutebrowser/[qutebrowser] and
|
||||
https://aur.archlinux.org/packages/qutebrowser-git/[qutebrowser-git].
|
||||
|
||||
You can install them like this:
|
||||
|
||||
----
|
||||
$ mkdir qutebrowser
|
||||
$ cd qutebrowser
|
||||
$ wget https://aur.archlinux.org/packages/qu/qutebrowser-git/PKGBUILD
|
||||
$ makepkg -si
|
||||
----
|
||||
|
||||
or you could use an AUR helper, e.g. `yaourt -S qutebrowser-git`.
|
||||
|
||||
On Gentoo
|
||||
---------
|
||||
|
||||
A dedicated overlay is available on
|
||||
https://github.com/posativ/qutebrowser-overlay[GitHub]. To install it, add the
|
||||
overlay with http://wiki.gentoo.org/wiki/Layman[layman]:
|
||||
|
||||
----
|
||||
# wget https://raw.githubusercontent.com/posativ/qutebrowser-overlay/master/overlays.xml -O /etc/layman/overlays/qutebrowser.xml
|
||||
# layman -a qutebrowser
|
||||
----
|
||||
|
||||
Note, that Qt5 is available in the portage tree, but masked. You may need to do
|
||||
a lot of keywording to install qutebrowser. Also make sure you have `python3_4`
|
||||
in your `PYTHON_TARGETS` (`/etc/portage/make.conf`) and rebuild your system
|
||||
(`emerge -uDNav @world`). Afterwards, you can install qutebrowser:
|
||||
|
||||
----
|
||||
# emerge -av qutebrowser
|
||||
----
|
||||
|
||||
On Windows
|
||||
----------
|
||||
|
||||
You can either use one of the
|
||||
https://github.com/The-Compiler/qutebrowser/releases[prebuilt standalone
|
||||
packages or MSI installers], or install manually:
|
||||
|
||||
* Use the installer from http://www.python.org/downloads[python.org] to get
|
||||
Python 3 (be sure to install pip).
|
||||
* Use the installer from
|
||||
http://www.riverbankcomputing.com/software/pyqt/download5[Riverbank computing]
|
||||
to get Qt and PyQt5.
|
||||
* Run `pip install virtualenv` or
|
||||
http://www.lfd.uci.edu/~gohlke/pythonlibs/#virtualenv[the installer from here]
|
||||
to install virtualenv.
|
||||
|
||||
Then run the supplied script to run qutebrowser inside a
|
||||
https://virtualenv.pypa.io/en/latest/virtualenv.html[virtualenv]:
|
||||
|
||||
----
|
||||
# python3 scripts/init_venv.py
|
||||
----
|
||||
|
||||
This installs all needed Python dependencies in a `.venv` subfolder. The
|
||||
system-wide Qt5/PyQt5 installations are used in the virtualenv.
|
||||
|
||||
On OS X
|
||||
-------
|
||||
|
||||
To install qutebrowser on OS X, you'll want a package manager, e.g.
|
||||
http://brew.sh/[Homebrew] or https://www.macports.org/[MacPorts]. Also make
|
||||
sure, you have https://itunes.apple.com/en/app/xcode/id497799835[XCode]
|
||||
installed to compile PyQt5 in a later step.
|
||||
|
||||
----
|
||||
$ brew install python3 pyqt5
|
||||
$ pip3.4 install qutebrowser
|
||||
----
|
||||
|
||||
if you are using Homebrew. For MacPorts, run:
|
||||
|
||||
----
|
||||
$ sudo port install python34 py34-jinja2 asciidoc py34-pygments py34-pyqt5
|
||||
$ sudo pip3.4 install qutebrowser
|
||||
----
|
||||
|
||||
The preferences for qutebrowser are stored in
|
||||
`~/Library/Preferences/qutebrowser`, the application data is stored in
|
||||
`~/Library/Application Support/qutebrowser`.
|
||||
|
||||
Packagers
|
||||
---------
|
||||
|
||||
There are example .desktop and icon files provided. They would go in the
|
||||
standard location for your distro (`/usr/share/applications` and
|
||||
`/usr/share/pixmaps` for example).
|
||||
|
||||
The normal `setup.py install` doesn't install these files, so you'll have to do
|
||||
it as part of the packaging process.
|
||||
@@ -1,294 +0,0 @@
|
||||
Crowdfunding backers
|
||||
====================
|
||||
|
||||
2017
|
||||
----
|
||||
|
||||
Mid-2017, qutebrowser had its
|
||||
https://www.kickstarter.com/projects/the-compiler/qutebrowser-v10-with-per-domain-settings[second crowdfunding]
|
||||
with the goal of implementing the new config system and releasing v1.0.
|
||||
|
||||
Thanks a lot to the following people who contributed to it:
|
||||
|
||||
Gold sponsors
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
TODO
|
||||
|
||||
Silver sponsors
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
TODO
|
||||
|
||||
Other sponsors
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
TODO: people with t-shirts or higher pledge levels
|
||||
|
||||
- 7scan
|
||||
- Alex Suykov
|
||||
- Alexey Zhikhartsev
|
||||
- Allan Nordhøy
|
||||
- Anirudh Sanjeev
|
||||
- Anssi Puustinen
|
||||
- Benedikt Steindorf
|
||||
- Bernardo Kuri
|
||||
- Blaise Duszynski
|
||||
- Bostan
|
||||
- Bruno Oliveira
|
||||
- Colin Jacobs
|
||||
- Daniel Andersson
|
||||
- Danilo
|
||||
- David Beley
|
||||
- David Hollings
|
||||
- David Parrish
|
||||
- Derin Yarsuvat
|
||||
- Dmytro Kostiuchenko
|
||||
- Frederik Thorøe
|
||||
- G4v4g4i
|
||||
- Gyula Teleki
|
||||
- H
|
||||
- Hosaka
|
||||
- Iordanis Grigoriou
|
||||
- Isaac Sandaljian
|
||||
- Jakub Podeszwik
|
||||
- Jamie Anderson
|
||||
- Jasper Woudenberg
|
||||
- Jens Højgaard
|
||||
- Johannes
|
||||
- John Baber-Lucero
|
||||
- Jonas Schürmann
|
||||
- Kenichiro Ito
|
||||
- Kenny Low
|
||||
- Lars Ivar Igesund
|
||||
- Lucas Aride Moulin
|
||||
- Ludovic Chabant
|
||||
- Lukas Gierth
|
||||
- Marulkan
|
||||
- Matthew Chun-Lum
|
||||
- Matthew Cronen
|
||||
- Matthew Quigley
|
||||
- Michael Schönwälder
|
||||
- Mika Kutila
|
||||
- Mitchell Stokes
|
||||
- Nathan Howell
|
||||
- Nathan Schlehlein
|
||||
- Noël Zindel
|
||||
- Obri
|
||||
- Patrik Peng
|
||||
- Peter DiMarco
|
||||
- Peter Rice
|
||||
- Philipp Middendorf
|
||||
- Pkill9
|
||||
- Prescott
|
||||
- Robotichead
|
||||
- Roshless
|
||||
- Ryan Ellis
|
||||
- Ryan P Deslandes
|
||||
- Sam Doshi
|
||||
- Sam Stone
|
||||
- Sean Herman
|
||||
- Sebastian Frysztak
|
||||
- Shelby Cruver
|
||||
- SirCmpwn
|
||||
- Soham Pal
|
||||
- Stewart Webb
|
||||
- Sven Reinecke
|
||||
- Tom Bass
|
||||
- Tomas Slusny
|
||||
- Tomasz Kramkowski
|
||||
- Tommy Thomas
|
||||
- Vasilij Schneidermann
|
||||
- Vlaaaaaaad
|
||||
- beanieuptop
|
||||
- demure
|
||||
- evenorbert
|
||||
- fishss
|
||||
- gsnewmark
|
||||
- guillermohs9
|
||||
- hubcaps
|
||||
- lobachevsky
|
||||
- neodarz
|
||||
- nihlaeth
|
||||
- notbenh
|
||||
- patrick suwanvithaya
|
||||
- pyratebeard
|
||||
- randm_dave
|
||||
- sabreman
|
||||
- toml
|
||||
- vimja
|
||||
- wiz
|
||||
- 43 Anonymous
|
||||
|
||||
2016
|
||||
----
|
||||
|
||||
Mid-2016, qutebrowser did run a http://igg.me/at/qutebrowser[crowdfunding] for
|
||||
QtWebEngine support in qutebrowser.
|
||||
|
||||
Thanks a lot to the following people who contributed to it:
|
||||
|
||||
Gold sponsors
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
- Chris Salzberg
|
||||
- Clayton Craft
|
||||
- Jean-Louis Fuchs
|
||||
- Matthias Lisin
|
||||
- 1 Anonymous
|
||||
|
||||
Day sponsors
|
||||
~~~~~~~~~~~~
|
||||
|
||||
- Agent 42
|
||||
- Iggy Jackson
|
||||
- James B
|
||||
- Rudi Seitz
|
||||
- Tim „Das MooL“ Wegener
|
||||
- amd1212
|
||||
- gavtroy
|
||||
- 4 Anonymous
|
||||
|
||||
Other sponsors
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
- AP M
|
||||
- Alessandro Balzano
|
||||
- Allan Nordhøy
|
||||
- Andor Uhlar
|
||||
- Andreas Leppert
|
||||
- Andreas Saga Romsdal
|
||||
- Andrew Rogers / tuxlovesyou
|
||||
- André Glüpker
|
||||
- Arian Sanusi
|
||||
- Arin Lares
|
||||
- Assaf Lavie
|
||||
- Baptiste Wicht
|
||||
- Benjamin Richter
|
||||
- Benjamin Schnitzler
|
||||
- Bernardo Kuri
|
||||
- Boris Kourtoukov
|
||||
- Brian Buccola
|
||||
- Bruno Oliveira
|
||||
- Bryan Gilbert
|
||||
- Cassandra Rebecca Ruppen
|
||||
- Charles Saternos
|
||||
- Chris H
|
||||
- Christian Karl
|
||||
- Christian Lange
|
||||
- Christian Strasser
|
||||
- Colin O'Brien
|
||||
- Corsin Pfister
|
||||
- Cosmin Popescu
|
||||
- Daniel Andersson
|
||||
- David Wilson
|
||||
- Demure Demeanor
|
||||
- Doug Stone-Weaver
|
||||
- Eero Kari
|
||||
- Enric Morales
|
||||
- Eric Krohn
|
||||
- Eskild Hustvedt
|
||||
- Federico Panico
|
||||
- Felix Van der Jeugt
|
||||
- Francis Tseng
|
||||
- Geir Isene
|
||||
- George Voronin
|
||||
- German Correa
|
||||
- Grady Martin
|
||||
- Gregor Böhl
|
||||
- Guilherme Stein
|
||||
- Hannes Doyle
|
||||
- Hasan Soydabas
|
||||
- Ian Scott
|
||||
- Jacob Boldman
|
||||
- Jacob Wikmark
|
||||
- Jan Verbeek
|
||||
- Jarrod Seccombe
|
||||
- Joel Bradshaw
|
||||
- Johannes Martinsson
|
||||
- Jonas Schürmann
|
||||
- Josh Medeiros
|
||||
- José Alberto Orejuela García
|
||||
- Julie Engel
|
||||
- Jörg Behrmann
|
||||
- Jørgen Skancke
|
||||
- Kevin Velghe
|
||||
- Konstantin Shmelkov
|
||||
- Kyle Frazer
|
||||
- Lukas Gierth
|
||||
- Mar v Leeuwaarde
|
||||
- Marek Roszman
|
||||
- Marius Betz
|
||||
- Marius Krämer
|
||||
- Markus Schmidinger
|
||||
- Martin Gabelmann
|
||||
- Martin Zimmermann
|
||||
- Mathias Fußenegger
|
||||
- Maxime Wack
|
||||
- Michał Góral
|
||||
- Nathan Isom
|
||||
- Nathanael Philipp
|
||||
- Nils Stål
|
||||
- Oliver Hope
|
||||
- Oskar Nyberg
|
||||
- Pablo Navarro
|
||||
- Panashe M. Fundira
|
||||
- Patric Schmitz
|
||||
- Pete M
|
||||
- Peter Smith
|
||||
- Phil Collins
|
||||
- Philipp Hansch
|
||||
- Philipp Kuhnz
|
||||
- Raphael Khaiat
|
||||
- Raphael Pierzina
|
||||
- Renan Guilherme
|
||||
- Rick Losie
|
||||
- Robert Cross
|
||||
- Roy Van Ginneken
|
||||
- Rupus Reinefjord
|
||||
- Ryan Roden-Corrent
|
||||
- Samir Benmendil
|
||||
- Simon Giotta
|
||||
- Stephen England
|
||||
- Sverrir H Steindorsson
|
||||
- Tarcisio Fedrizzi
|
||||
- Thorsten Wißmann
|
||||
- Timon Stampfli
|
||||
- Tjelvar Olsson
|
||||
- Tomasz Kramkowski
|
||||
- Tsukiko Tsutsukakushi
|
||||
- Vasilij Schneidermann
|
||||
- Vinney Cavallo
|
||||
- Wesly Grefrath
|
||||
- Will Ware
|
||||
- Yousaf Khurshid
|
||||
- Zach Schultz
|
||||
- averrin
|
||||
- ben hengst
|
||||
- colin
|
||||
- craigtski47
|
||||
- dag.robole
|
||||
- daniel.m.kao
|
||||
- diepfann3
|
||||
- eamonn oneil
|
||||
- esakaforever
|
||||
- francois47
|
||||
- glspisso
|
||||
- gmccoy4242
|
||||
- gtcee3
|
||||
- jonathf
|
||||
- lapinski.maciej
|
||||
- lauri.hakko
|
||||
- ljanzen
|
||||
- mutilx9
|
||||
- nussgipfel
|
||||
- oed
|
||||
- p p
|
||||
- r.c.bruno.andre
|
||||
- robert.perce
|
||||
- sghctoma
|
||||
- targy
|
||||
- freelancer
|
||||
- pupu
|
||||
- regines
|
||||
- 37 Anonymous
|
||||
225
doc/faq.asciidoc
@@ -1,225 +0,0 @@
|
||||
Frequently asked questions
|
||||
==========================
|
||||
:title: Frequently asked questions
|
||||
The Compiler <mail@qutebrowser.org>
|
||||
|
||||
[qanda]
|
||||
What is qutebrowser based on?::
|
||||
qutebrowser uses http://www.python.org/[Python], http://qt.io/[Qt] and
|
||||
http://www.riverbankcomputing.com/software/pyqt/intro[PyQt].
|
||||
+
|
||||
The concept of it is largely inspired by http://portix.bitbucket.org/dwb/[dwb]
|
||||
and http://www.vimperator.org/vimperator[Vimperator]. Many actions and
|
||||
key bindings are similar to dwb.
|
||||
|
||||
Why another browser?::
|
||||
It might be hard to believe, but I didn't find any browser which I was
|
||||
happy with, so I started to write my own. Also, I needed a project to get
|
||||
into writing GUI applications with Python and
|
||||
link:http://qt.io/[Qt]/link:http://www.riverbankcomputing.com/software/pyqt/intro[PyQt].
|
||||
+
|
||||
Read the next few questions to find out why I was unhappy with existing
|
||||
software.
|
||||
|
||||
What's wrong with link:http://portix.bitbucket.org/dwb/[dwb]/link:http://sourceforge.net/projects/vimprobable/[vimprobable]/link:https://mason-larobina.github.io/luakit/[luakit]/link:http://pwmt.org/projects/jumanji/[jumanji]/... (projects based on WebKitGTK)?::
|
||||
Most of them are based on the http://webkitgtk.org/[WebKitGTK+]
|
||||
http://webkitgtk.org/reference/webkitgtk/stable/index.html[WebKit1] API,
|
||||
which causes a lot of crashes. As the GTK API using WebKit1 is
|
||||
https://lists.webkit.org/pipermail/webkit-gtk/2014-March/001821.html[deprecated],
|
||||
these bugs are never going to be fixed.
|
||||
+
|
||||
The newer http://webkitgtk.org/reference/webkit2gtk/stable/index.html[WebKit2
|
||||
API] seems to lack basic features like proxy support, and almost no projects
|
||||
seem to have started porting to WebKit2 (I only know of
|
||||
http://www.uzbl.org/[uzbl]).
|
||||
+
|
||||
qutebrowser uses http://qt.io/[Qt] and http://wiki.qt.io/QtWebKit[QtWebKit]
|
||||
instead, which suffers from far less such crashes. It might switch to
|
||||
http://wiki.qt.io/QtWebEngine[QtWebEngine] in the future, which is based on
|
||||
Google's https://en.wikipedia.org/wiki/Blink_(layout_engine)[Blink] rendering
|
||||
engine.
|
||||
|
||||
What's wrong with https://www.mozilla.org/en-US/firefox/new/[Firefox] and link:http://5digits.org/pentadactyl/[Pentadactyl]/link:http://www.vimperator.org/vimperator[Vimperator]?::
|
||||
Firefox likes to break compatibility with addons on each upgrade, gets
|
||||
slower and more bloated with every upgrade, and has some
|
||||
https://blog.mozilla.org/advancingcontent/2014/02/11/publisher-transformation-with-users-at-the-center/[horrible
|
||||
ideas] lately.
|
||||
+
|
||||
Also, developing addons for it is a nightmare.
|
||||
|
||||
What's wrong with http://www.chromium.org/Home[Chromium] and https://vimium.github.io/[Vimium]?::
|
||||
The Chrome plugin API doesn't seem to allow much freedom for plugin
|
||||
writers, which results in Vimium not really having all the features you'd
|
||||
expect from a proper minimal, vim-like browser.
|
||||
|
||||
Why Python?::
|
||||
I enjoy writing Python since 2011, which made it one of the possible
|
||||
choices. I wanted to use http://qt.io/[Qt] because of
|
||||
http://wiki.qt.io/QtWebKit[QtWebKit] so I didn't have
|
||||
http://wiki.qt.io/Category:LanguageBindings[many other choices]. I don't
|
||||
like C++ and can't write it very well, so that wasn't an alternative.
|
||||
|
||||
But isn't Python too slow for a browser?::
|
||||
http://www.infoworld.com/d/application-development/van-rossum-python-not-too-slow-188715[No.]
|
||||
I believe efficiency while coding is a lot more important than efficiency
|
||||
while running. Also, most of the heavy lifting of qutebrowser is done by Qt
|
||||
and WebKit in C++, with the
|
||||
https://wiki.python.org/moin/GlobalInterpreterLock[GIL] released.
|
||||
|
||||
Is there an adblocker?::
|
||||
There is a host-based adblocker which takes /etc/hosts-like lists. A "real"
|
||||
adblocker has a
|
||||
http://www.reddit.com/r/programming/comments/25j41u/adblock_pluss_effect_on_firefoxs_memory_usage/chhpomw[big
|
||||
impact] on browsing speed and
|
||||
https://blog.mozilla.org/nnethercote/2014/05/14/adblock-pluss-effect-on-firefoxs-memory-usage/[RAM
|
||||
usage], so implementing support for AdBlockPlus-like lists is currently not
|
||||
a priority.
|
||||
|
||||
How do I play Youtube videos with mpv?::
|
||||
You can easily add a key binding to play youtube videos inside a real video
|
||||
player - optionally even with hinting for links:
|
||||
+
|
||||
----
|
||||
:bind m spawn mpv {url}
|
||||
:bind M hint links spawn mpv {hint-url}
|
||||
----
|
||||
+
|
||||
Note that you might need an additional package (e.g.
|
||||
https://www.archlinux.org/packages/community/any/youtube-dl/[youtube-dl] on
|
||||
Archlinux) to play web videos with mpv.
|
||||
+
|
||||
There is a very useful script for mpv, which emulates "unique application"
|
||||
functionality. This way you can add links to the mpv playlist instead of
|
||||
playing them all at once.
|
||||
+
|
||||
You can find the script here: https://github.com/mpv-player/mpv/blob/master/TOOLS/umpv
|
||||
+
|
||||
It also works nicely with rapid hints:
|
||||
+
|
||||
----
|
||||
:bind m spawn umpv {url}
|
||||
:bind M hint links spawn umpv {hint-url}
|
||||
:bind ;M hint --rapid links spawn umpv {hint-url}
|
||||
----
|
||||
|
||||
How do I use qutebrowser with mutt?::
|
||||
Due to a Qt limitation, local files without `.html` extensions are
|
||||
"downloaded" instead of displayed, see
|
||||
https://github.com/qutebrowser/qutebrowser/issues/566[#566]. You can work
|
||||
around this by using this in your `mailcap`:
|
||||
+
|
||||
----
|
||||
text/html; mv %s %s.html && qutebrowser %s.html >/dev/null 2>/dev/null; needsterminal;
|
||||
----
|
||||
|
||||
What is the difference between bookmarks and quickmarks?::
|
||||
Bookmarks will always use the title of the website as their name, but with quickmarks
|
||||
you can set your own title.
|
||||
+
|
||||
For example, if you bookmark multiple food recipe websites and use `:open`,
|
||||
you have to type the title or address of the website.
|
||||
+
|
||||
When using quickmark, you can give them all names, like
|
||||
`foodrecipes1`, `foodrecipes2` and so on. When you type
|
||||
`:open foodrecipes`, you will see a list of all the food recipe sites,
|
||||
without having to remember the exact website title or address.
|
||||
|
||||
How do I use spell checking?::
|
||||
Configuring spell checking in qutebrowser depends on the backend in use
|
||||
(see https://github.com/qutebrowser/qutebrowser/issues/700[#700] for
|
||||
a more detailed discussion).
|
||||
+
|
||||
For QtWebKit:
|
||||
|
||||
. Install https://github.com/QupZilla/qtwebkit-plugins[qtwebkit-plugins].
|
||||
. Note: with QtWebKit reloaded you may experience some issues. See
|
||||
https://github.com/QupZilla/qtwebkit-plugins/issues/10[#10].
|
||||
. The dictionary to use is taken from the `DICTIONARY` environment variable.
|
||||
The default is `en_US`. For example to use Dutch spell check set `DICTIONARY`
|
||||
to `nl_NL`; you can't use multiple dictionaries or change them at runtime at
|
||||
the moment.
|
||||
(also see the README file for `qtwebkit-plugins`).
|
||||
. Remember to install the hunspell dictionaries if you don't have them already
|
||||
(most distros should have packages for this).
|
||||
|
||||
+
|
||||
For QtWebEngine:
|
||||
|
||||
. Make sure your versions of PyQt and Qt are 5.8 or higher.
|
||||
. Use `install_dict.py` script to install dictionaries.
|
||||
Run the script with `-h` for the parameter description.
|
||||
. Set `spellcheck.languages` to the desired list of languages, e.g.:
|
||||
`:set spellcheck.languages "['en-US', 'pl-PL']"`
|
||||
|
||||
How do I use Tor with qutebrowser?::
|
||||
Start tor on your machine, and do `:set network proxy socks://localhost:9050/`
|
||||
in qutebrowser. Note this won't give you the same amount of fingerprinting
|
||||
protection that the Tor Browser does, but it's useful to be able to access
|
||||
`.onion` sites.
|
||||
|
||||
Why does J move to the next (right) tab, and K to the previous (left) one?::
|
||||
One reason is because https://bitbucket.org/portix/dwb[dwb] did it that way,
|
||||
and qutebrowser's keybindings are designed to be compatible with dwb's.
|
||||
The rationale behind it is that J is "down" in vim, and K is "up", which
|
||||
corresponds nicely to "next"/"previous". It also makes much more sense with
|
||||
vertical tabs (e.g. `:set tabs position left`).
|
||||
|
||||
What's the difference between insert and passthrough mode?::
|
||||
They are quite similar, but insert mode has some bindings (like `Ctrl-e` to
|
||||
open an editor) while passthrough mode only has escape bound. It might also
|
||||
be useful to rebind escape to something else in passthrough mode only, to be
|
||||
able to send an escape keypress to the website.
|
||||
|
||||
Why takes it longer to open an URL in qutebrowser than in chromium?::
|
||||
When opening an URL in an existing instance the normal qutebrowser
|
||||
Python script is started and a few PyQt libraries need to be
|
||||
loaded until it is detected that there is an instance running
|
||||
where the URL is then passed to. This takes some time.
|
||||
One workaround is to use this
|
||||
https://github.com/qutebrowser/qutebrowser/blob/master/scripts/open_url_in_instance.sh[script]
|
||||
and place it in your $PATH with the name "qutebrowser". This
|
||||
script passes the URL via an unix socket to qutebrowser (if its
|
||||
running already) using socat which is much faster and starts a new
|
||||
qutebrowser if it is not running already. Also check if you want
|
||||
to use webengine as backend in line 17 and change it to your
|
||||
needs.
|
||||
|
||||
== Troubleshooting
|
||||
|
||||
Configuration not saved after modifying config.::
|
||||
When editing your config file manually, qutebrowser must be exited completely.
|
||||
This can be done by issuing the command `:quit` or by pressing `Ctrl+q`.
|
||||
|
||||
Unable to view flash content.::
|
||||
If you have flash installed for on your system, it's necessary to enable plugins
|
||||
to use the flash plugin. Using the command `:set content.plugins true`
|
||||
in qutebrowser will enable plugins. Packages for flash should
|
||||
be provided for your platform or it can be obtained from
|
||||
http://get.adobe.com/flashplayer/[Adobe].
|
||||
|
||||
Experiencing freezing on sites like duckduckgo and youtube.::
|
||||
This issue could be caused by stale plugin files installed by `mozplugger`
|
||||
if mozplugger was subsequently removed.
|
||||
Try exiting qutebrowser and removing `~/.mozilla/plugins/mozplugger*.so`.
|
||||
See https://github.com/qutebrowser/qutebrowser/issues/357[Issue #357]
|
||||
for more details.
|
||||
|
||||
When using QtWebEngine, qutebrowser reports "Render Process Crashed" and the console prints a traceback on Gentoo Linux or another Source-Based Distro::
|
||||
As stated in https://gcc.gnu.org/gcc-6/changes.html[GCC's Website] GCC 6 has introduced some optimizations that could break non-conforming codebases, like QtWebEngine. +
|
||||
As a workaround, you can disable the nullpointer check optimization by adding the -fno-delete-null-pointer-checks flag while compiling. +
|
||||
On gentoo, you just need to add it into your make.conf, like this: +
|
||||
|
||||
CFLAGS="... -fno-delete-null-pointer-checks"
|
||||
CXXFLAGS="... -fno-delete-null-pointer-checks"
|
||||
+
|
||||
And then re-emerging qtwebengine with: +
|
||||
|
||||
emerge -1 qtwebengine
|
||||
|
||||
My issue is not listed.::
|
||||
If you experience any segfaults or crashes, you can report the issue in
|
||||
https://github.com/qutebrowser/qutebrowser/issues[the issue tracker] or
|
||||
using the `:report` command.
|
||||
If you are reporting a segfault, make sure you read the
|
||||
link:doc/stacktrace.asciidoc[guide] on how to report them with all needed
|
||||
information.
|
||||
@@ -1,369 +0,0 @@
|
||||
Configuring qutebrowser
|
||||
=======================
|
||||
|
||||
IMPORTANT: qutebrowser's configuration system was completely rewritten in
|
||||
September 2017. This information is not applicable to older releases, and older
|
||||
information elsewhere might be outdated. **If you had an old configuration
|
||||
around and upgraded, this page will automatically open once**. To view it at a
|
||||
later time, use the `:help` command.
|
||||
|
||||
Migrating older configurations
|
||||
------------------------------
|
||||
|
||||
qutebrowser does no automatic migration for the new configuration. However,
|
||||
there's a special link:qute://configdiff/old[configdiff] page in qutebrowser,
|
||||
which will show you the changes you did in your old configuration, compared to
|
||||
the old defaults.
|
||||
|
||||
Other changes in default settings:
|
||||
|
||||
- `<Up>` and `<Down>` in the completion now navigate through command history
|
||||
instead of selecting completion items. You can get back the old behavior by
|
||||
doing:
|
||||
+
|
||||
----
|
||||
:bind -m command <Up> completion-item-focus prev
|
||||
:bind -m command <Down> completion-item-focus next
|
||||
----
|
||||
|
||||
- The default for `completion.web_history_max_items` is now set to `-1`, showing
|
||||
an unlimited number of items in the completion for `:open` as the new
|
||||
sqlite-based completion is much faster. If the `:open` completion is too slow
|
||||
on your machine, set an appropriate limit again.
|
||||
|
||||
Configuring qutebrowser via the user interface
|
||||
----------------------------------------------
|
||||
|
||||
The easy (but less flexible) way to configure qutebrowser is using its user
|
||||
interface or command line. Changes you make this way are immediately active
|
||||
(with the exception of a few settings, where this is pointed out in the
|
||||
documentation) and are persisted in an `autoconfig.yml` file.
|
||||
|
||||
The `autoconfig.yml` file is located in the "config" folder listed on the
|
||||
link:qute://version[] page. On macOS, the "auto config" folder is used, which is
|
||||
different from where hand-written config files are kept.
|
||||
|
||||
However, **do not** edit `autoconfig.yml` by hand. Instead, see the next
|
||||
section.
|
||||
|
||||
If you want to customize many settings, you can open the link:qute://settings[]
|
||||
page by running `:set` without any arguments, where all settings are listed and
|
||||
customizable.
|
||||
|
||||
Using the link:commands.html#set[`:set`] command and command completion, you
|
||||
can quickly set settings interactively, for example `:set tabs.position left`.
|
||||
|
||||
To get more help about a setting, use e.g. `:help tabs.position`.
|
||||
|
||||
To bind and unbind keys, you can use the link:commands.html#bind[`:bind`] and
|
||||
link:commands.html#unbind[`:unbind`] commands:
|
||||
|
||||
- Binding the key chain `,v` to the `:spawn mpv {url}` command:
|
||||
`:bind ,v spawn mpv {url}`
|
||||
- Unbinding the same key chain: `:unbind ,v`
|
||||
|
||||
Key chains starting with a comma are ideal for custom bindings, as the comma key
|
||||
will never be used in a default keybinding.
|
||||
|
||||
See the help pages linked above (or `:help :bind`, `:help :unbind`) for more
|
||||
information.
|
||||
|
||||
Other useful commands for config manipulation are
|
||||
link:commands.html#config-unset[`:config-unset`] to reset a value to its default,
|
||||
link:commands.html#config-clear[`:config-clear`] to reset the entire configuration,
|
||||
and link:commands.html#config-cycle[`:config-cycle`] to cycle a setting between
|
||||
different values.
|
||||
|
||||
Configuring qutebrowser via config.py
|
||||
-------------------------------------
|
||||
|
||||
For more powerful configuration possibilities, you can create a `config.py`
|
||||
file. Since it's a Python file, you have much more flexibility for
|
||||
configuration. Note that qutebrowser will never touch this file - this means
|
||||
you'll be responsible for updating it when upgrading to a newer qutebrowser
|
||||
version.
|
||||
|
||||
You can run `:config-edit` inside qutebrowser to open the file in your editor,
|
||||
`:config-source` to reload the file (`:config-edit` does this automatically), or
|
||||
`:config-write-py --defaults` to write a template file to work with.
|
||||
|
||||
The file should be located in the "config" location listed on
|
||||
link:qute://version[], which is typically `~/.config/qutebrowser/config.py` on
|
||||
Linux, `~/.qutebrowser/config.py` on macOS, and
|
||||
`%APPDATA%/qutebrowser/config.py` on Windows.
|
||||
|
||||
Two global objects are pre-defined when running `config.py`: `c` and `config`.
|
||||
|
||||
Changing settings
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
While you can set settings using the `config.set()` method (which is explained
|
||||
in the next section), it's easier to use the `c` shorthand object to easily set
|
||||
settings like this:
|
||||
|
||||
.config.py:
|
||||
[source,python]
|
||||
----
|
||||
c.tabs.position = "left"
|
||||
c.completion.shrink = True
|
||||
----
|
||||
|
||||
Note that qutebrowser does some Python magic so it's able to warn you about
|
||||
mistyped config settings. As an example, if you do `c.tabs.possition = "left"`,
|
||||
you'll get an error when starting.
|
||||
|
||||
See the link:settings.html[settings help page] for all available settings. The
|
||||
accepted values depend on the type of the option. Commonly used are:
|
||||
|
||||
- Strings: `c.tabs.position = "left"`
|
||||
- Booleans: `c.completion.shrink = True`
|
||||
- Integers: `c.messages.timeout = 5000`
|
||||
- Dictionaries:
|
||||
* `c.headers.custom = {'X-Hello': 'World', 'X-Awesome': 'yes'}` to override
|
||||
any other values in the dictionary.
|
||||
* `c.aliases['foo'] = 'message-info foo'` to add a single value.
|
||||
- Lists:
|
||||
* `c.url.start_pages = ["https://www.qutebrowser.org/"]` to override any
|
||||
previous elements.
|
||||
* `c.url.start_pages.append("https://www.python.org/")` to add a new value.
|
||||
|
||||
Any other config types (e.g. a color) are specified as a string. The only
|
||||
exception is the `Regex` type, which can take either a string (with an `r`
|
||||
prefix to preserve backslashes) or a Python regex object:
|
||||
|
||||
- `c.hints.next_regexes.append(r'\bvor\b')`
|
||||
- `c.hints.prev_regexes.append(re.compile(r'\bzurück\b'))`
|
||||
|
||||
If you want to read a setting, you can use the `c` object to do so as well:
|
||||
`c.colors.tabs.even.bg = c.colors.tabs.odd.bg`.
|
||||
|
||||
|
||||
Using strings for setting names
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want to set settings based on their name as a string, use the
|
||||
`config.set` method:
|
||||
|
||||
.config.py:
|
||||
[source,python]
|
||||
----
|
||||
# Equivalent to:
|
||||
# c.content.javascript.enabled = False
|
||||
config.set('content.javascript.enabled', False)
|
||||
----
|
||||
|
||||
To read a setting, use the `config.get` method:
|
||||
|
||||
[source,python]
|
||||
----
|
||||
# Equivalent to:
|
||||
# color = c.colors.completion.fg
|
||||
color = config.get('colors.completion.fg')
|
||||
----
|
||||
|
||||
Binding keys
|
||||
~~~~~~~~~~~~
|
||||
|
||||
While it's possible to change the `bindings.commands` setting to bind keys, it's
|
||||
preferred to use the `config.bind` command. Doing so ensures the commands are
|
||||
valid and normalizes different expressions which map to the same key.
|
||||
|
||||
For details on how to specify keys and the available modes, see the
|
||||
link:settings.html#bindings.commands[documentation] for the `bindings.commands`
|
||||
setting.
|
||||
|
||||
To bind a key:
|
||||
|
||||
.config.py:
|
||||
[source,python]
|
||||
----
|
||||
config.bind('<Ctrl-v>', 'spawn mpv {url}')
|
||||
----
|
||||
|
||||
To bind a key in a mode other than `'normal'`, add a `mode` argument:
|
||||
|
||||
[source,python]
|
||||
----
|
||||
config.bind('<Ctrl-y>', 'prompt-yes', mode='prompt')
|
||||
----
|
||||
|
||||
To unbind a key (either a key which has been bound before, or a default binding):
|
||||
|
||||
[source,python]
|
||||
----
|
||||
config.unbind('<Ctrl-v>', mode='normal')
|
||||
----
|
||||
|
||||
To bind keys without modifiers, specify a key chain to bind as a string. Key
|
||||
chains starting with a comma are ideal for custom bindings, as the comma key
|
||||
will never be used in a default keybinding.
|
||||
|
||||
[source,python]
|
||||
----
|
||||
config.bind(',v', 'spawn mpv {url}')
|
||||
----
|
||||
|
||||
To suppress loading of any default keybindings, you can set
|
||||
`c.bindings.default = {}`.
|
||||
|
||||
Loading `autoconfig.yml`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
By default, all customization done via `:set`, `:bind` and `:unbind` is
|
||||
temporary as soon as a `config.py` exists. The settings done that way are always
|
||||
saved in the `autoconfig.yml` file, but you'll need to explicitly load it in
|
||||
your `config.py` by doing:
|
||||
|
||||
.config.py:
|
||||
[source,python]
|
||||
----
|
||||
config.load_autoconfig()
|
||||
----
|
||||
|
||||
If you do so at the top of your file, your `config.py` settings will take
|
||||
precedence as they overwrite the settings done in `autoconfig.yml`.
|
||||
|
||||
Importing other modules
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can import any module from the
|
||||
https://docs.python.org/3/library/index.html[Python standard library] (e.g.
|
||||
`import os.path`), as well as any module installed in the environment
|
||||
qutebrowser is run with.
|
||||
|
||||
If you have an `utils.py` file in your qutebrowser config folder, you can import
|
||||
that via `import utils` as well.
|
||||
|
||||
While it's in some cases possible to import code from the qutebrowser
|
||||
installation, doing so is unsupported and discouraged.
|
||||
|
||||
Getting the config directory
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you need to get the qutebrowser config directory, you can do so by reading
|
||||
`config.configdir`. Similarily, you can get the qutebrowser data directory via
|
||||
`config.datadir`.
|
||||
|
||||
This gives you a https://docs.python.org/3/library/pathlib.html[`pathlib.Path`
|
||||
object], on which you can use `/` to add more directory parts, or `str(...)` to
|
||||
get a string:
|
||||
|
||||
.config.py:
|
||||
[source,python]
|
||||
----
|
||||
print(str(config.configdir / 'config.py')
|
||||
----
|
||||
|
||||
Handling errors
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
If there are errors in your `config.py`, qutebrowser will try to apply as much
|
||||
of it as possible, and show an error dialog before starting.
|
||||
|
||||
qutebrowser tries to display errors which are easy to understand even for people
|
||||
who are not used to writing Python. If you see a config error which you find
|
||||
confusing or you think qutebrowser could handle better, please
|
||||
https://github.com/qutebrowser/qutebrowser/issues[open an issue]!
|
||||
|
||||
Recipes
|
||||
~~~~~~~
|
||||
|
||||
Reading a YAML file
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To read a YAML config like this:
|
||||
|
||||
.config.yml:
|
||||
----
|
||||
tabs.position: left
|
||||
tabs.show: switching
|
||||
----
|
||||
|
||||
You can use:
|
||||
|
||||
.config.py:
|
||||
[source,python]
|
||||
----
|
||||
import yaml
|
||||
|
||||
with (config.configdir / 'config.yml').open() as f:
|
||||
yaml_data = yaml.load(f)
|
||||
|
||||
for k, v in yaml_data.items():
|
||||
config.set(k, v)
|
||||
----
|
||||
|
||||
Reading a nested YAML file
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To read a YAML file with nested values like this:
|
||||
|
||||
.colors.yml:
|
||||
----
|
||||
colors:
|
||||
statusbar:
|
||||
normal:
|
||||
bg: lime
|
||||
fg: black
|
||||
url:
|
||||
fg: red
|
||||
----
|
||||
|
||||
You can use:
|
||||
|
||||
.config.py:
|
||||
[source,python]
|
||||
----
|
||||
import yaml
|
||||
|
||||
with (config.configdir / 'colors.yml').open() as f:
|
||||
yaml_data = yaml.load(f)
|
||||
|
||||
def dict_attrs(obj, path=''):
|
||||
if isinstance(obj, dict):
|
||||
for k, v in obj.items():
|
||||
yield from dict_attrs(v, '{}.{}'.format(path, k) if path else k)
|
||||
else:
|
||||
yield path, obj
|
||||
|
||||
for k, v in dict_attrs(yaml_data):
|
||||
config.set(k, v)
|
||||
----
|
||||
|
||||
Note that this won't work for values which are dictionaries.
|
||||
|
||||
Binding chained commands
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you have a lot of chained commands you want to bind, you can write a helper
|
||||
to do so:
|
||||
|
||||
[source,python]
|
||||
----
|
||||
def bind_chained(key, *commands):
|
||||
config.bind(key, ' ;; '.join(commands))
|
||||
|
||||
bind_chained('<Escape>', 'clear-keychain', 'search')
|
||||
----
|
||||
|
||||
Avoiding flake8 errors
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you use an editor with flake8 integration which complains about `c` and `config` being undefined, you can use:
|
||||
|
||||
[source,python]
|
||||
----
|
||||
c = c # noqa: F821
|
||||
config = config # noqa: F821
|
||||
----
|
||||
|
||||
For type annotation support (note that those imports aren't guaranteed to be
|
||||
stable across qutebrowser versions):
|
||||
|
||||
[source,python]
|
||||
----
|
||||
from qutebrowser.config.configfiles import ConfigAPI # noqa: F401
|
||||
from qutebrowser.config.config import ConfigContainer # noqa: F401
|
||||
config = config # type: ConfigAPI # noqa: F821
|
||||
c = c # type: ConfigContainer # noqa: F821
|
||||
----
|
||||
@@ -6,14 +6,10 @@ Documentation
|
||||
|
||||
The following help pages are currently available:
|
||||
|
||||
* link:../quickstart.html[Quick start guide]
|
||||
* link:../faq.html[Frequently asked questions]
|
||||
* link:../changelog.html[Change Log]
|
||||
* link:quickstart.html[Quick start guide]
|
||||
* link:FAQ.html[Frequently asked questions]
|
||||
* link:commands.html[Documentation of commands]
|
||||
* link:configuring.html[Configuring qutebrowser]
|
||||
* link:settings.html[Documentation of settings]
|
||||
* link:../userscripts.html[How to write userscripts]
|
||||
* link:../contributing.html[Contributing to qutebrowser]
|
||||
|
||||
Getting help
|
||||
------------
|
||||
|
||||
|
Before Width: | Height: | Size: 989 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 32 KiB |
BIN
doc/img/main.png
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 26 KiB |
@@ -1,380 +0,0 @@
|
||||
Installing qutebrowser
|
||||
======================
|
||||
|
||||
toc::[]
|
||||
|
||||
NOTE: qutebrowser recently had some bigger dependency changes for v1.0.0, which
|
||||
means those instructions might be out of date in some places.
|
||||
https://github.com/qutebrowser/qutebrowser/blob/master/doc/contributing.asciidoc[Please help]
|
||||
updating them if you notice something being broken!
|
||||
|
||||
On Debian / Ubuntu
|
||||
------------------
|
||||
|
||||
How to install qutebrowser depends a lot on the version of Debian/Ubuntu you're
|
||||
running.
|
||||
|
||||
Debian Jessie / Ubuntu 14.04 LTS / Linux Mint < 18
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Those distributions only have Python 3.4 and a too old Qt version available,
|
||||
while qutebrowser requires Python 3.5 and Qt 5.7.1 or newer.
|
||||
|
||||
It should be possible to install Python 3.5 e.g. from the
|
||||
https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa[deadsnakes PPA] or via_ipca
|
||||
https://github.com/pyenv/pyenv[pyenv], but nobody tried that yet.
|
||||
|
||||
If you get qutebrowser running on those distributions, please
|
||||
https://github.com/qutebrowser/qutebrowser/blob/master/doc/contributing.asciidoc[contribute]
|
||||
to update this documentation!
|
||||
|
||||
Ubuntu 16.04 LTS / Linux Mint 18
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Ubuntu 16.04 doesn't come with an up-to-date engine (a new enough QtWebKit, or
|
||||
QtWebEngine). However, it comes with Python 3.5, so you can
|
||||
<<tox,install qutebrowser via tox>>.
|
||||
|
||||
Debian Stretch / Ubuntu 17.04 and newer
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Those versions come with QtWebEngine in the repositories. This makes it possible
|
||||
to install qutebrowser via the Debian package.
|
||||
|
||||
Install the dependencies via apt-get:
|
||||
|
||||
----
|
||||
# apt install python-tox python3-{lxml,pyqt5,sip,jinja2,pygments,yaml,attr} python3-pyqt5.qt{webengine,quick,opengl,sql} libqt5sql5-sqlite
|
||||
----
|
||||
|
||||
Get the qutebrowser package from the
|
||||
https://github.com/qutebrowser/qutebrowser/releases[release page] and download
|
||||
the https://qutebrowser.org/python3-pypeg2_2.15.2-1_all.deb[PyPEG2 package].
|
||||
|
||||
Install the packages:
|
||||
|
||||
----
|
||||
# dpkg -i python3-pypeg2_*_all.deb
|
||||
# dpkg -i qutebrowser_*_all.deb
|
||||
----
|
||||
|
||||
Some additional hints:
|
||||
|
||||
- Alternatively, you can <<tox,install qutebrowser via tox>> to get a newer
|
||||
QtWebEngine version.
|
||||
- If running from git, run the following to generate the documentation for the
|
||||
`:help` command:
|
||||
+
|
||||
----
|
||||
# apt-get install --no-install-recommends asciidoc source-highlight
|
||||
$ python3 scripts/asciidoc2html.py
|
||||
----
|
||||
|
||||
- If you prefer using QtWebKit, there's an up-to-date version available in
|
||||
Debian experimental, or from http://repo.paretje.be/unstable/[this repository]
|
||||
for Debian Stretch.
|
||||
- If video or sound don't work with QtWebKit, try installing the gstreamer plugins:
|
||||
+
|
||||
----
|
||||
# apt-get install gstreamer1.0-plugins-{bad,base,good,ugly}
|
||||
----
|
||||
|
||||
On Fedora
|
||||
---------
|
||||
|
||||
qutebrowser is available in the official repositories for Fedora 22 and newer.
|
||||
|
||||
----
|
||||
# dnf install qutebrowser
|
||||
----
|
||||
|
||||
It's also recommended to install `python3-qt5-webengine` and start with `--backend
|
||||
webengine` to use the new backend. v1.0.0 (which is not in the Fedora repos
|
||||
currently) uses QtWebEngine by default.
|
||||
|
||||
On Archlinux
|
||||
------------
|
||||
|
||||
qutebrowser is available in the official [community] repository.
|
||||
|
||||
----
|
||||
# pacman -S qutebrowser
|
||||
----
|
||||
|
||||
There is also a -git version available in the AUR:
|
||||
https://aur.archlinux.org/packages/qutebrowser-git/[qutebrowser-git].
|
||||
|
||||
You can install it using `makepkg` like this:
|
||||
|
||||
----
|
||||
$ git clone https://aur.archlinux.org/qutebrowser-git.git
|
||||
$ cd qutebrowser-git
|
||||
$ makepkg -si
|
||||
$ cd ..
|
||||
$ rm -r qutebrowser-git
|
||||
----
|
||||
|
||||
or you could use an AUR helper, e.g. `yaourt -S qutebrowser-git`.
|
||||
|
||||
If video or sound don't work with QtWebKit, try installing the gstreamer plugins:
|
||||
|
||||
----
|
||||
# pacman -S gst-plugins-{base,good,bad,ugly} gst-libav
|
||||
----
|
||||
|
||||
On Gentoo
|
||||
---------
|
||||
|
||||
The Gentoo packages (even the live version) are lagging behind a lot and are
|
||||
effectively unmaintained. If you want to create and maintain an official
|
||||
qutebrowser overlay for Gentoo, please mailto:mail@qutebrowser.org[get in
|
||||
touch.]
|
||||
|
||||
It's recommended to <<tox,install qutebrowser via tox>> instead.
|
||||
|
||||
To get an up-to-date QtWebKit, you can use
|
||||
https://gist.github.com/annulen/309569fb61e5d64a703c055c1e726f71[this ebuild].
|
||||
|
||||
If video or sound don't work with QtWebKit, try installing the gstreamer
|
||||
plugins:
|
||||
|
||||
----
|
||||
# emerge -av gst-plugins-{base,good,bad,ugly,libav}
|
||||
----
|
||||
|
||||
To be able to play videos with proprietary codecs with QtWebEngine, you will
|
||||
need to turn off the `bindist` flag for `dev-qt/qtwebengine`.
|
||||
|
||||
See the https://wiki.gentoo.org/wiki/Qutebrowser#USE_flags[Gentoo Wiki] for
|
||||
more information.
|
||||
|
||||
On Void Linux
|
||||
-------------
|
||||
|
||||
qutebrowser is available in the official repositories and can be installed
|
||||
with:
|
||||
|
||||
----
|
||||
# xbps-install qutebrowser
|
||||
----
|
||||
|
||||
It's currently recommended to install `python3-PyQt5-webengine` and
|
||||
`python3-PyQt5-opengl`, then start with `--backend webengine` to use the new
|
||||
backend.
|
||||
|
||||
Since the v1.0 release, qutebrowser uses QtWebEngine by default.
|
||||
|
||||
On NixOS
|
||||
--------
|
||||
|
||||
Nixpkgs collection contains `pkgs.qutebrowser` since June 2015. You can install
|
||||
it with:
|
||||
|
||||
----
|
||||
$ nix-env -i qutebrowser
|
||||
----
|
||||
|
||||
It's recommended to install `qt5.qtwebengine` and start with
|
||||
`--backend webengine` to use the new backend.
|
||||
|
||||
Since the v1.0 release, qutebrowser uses QtWebEngine by default.
|
||||
|
||||
On openSUSE
|
||||
-----------
|
||||
|
||||
There are prebuilt RPMs available at https://software.opensuse.org/download.html?project=network&package=qutebrowser[OBS].
|
||||
|
||||
To use the QtWebEngine backend, install `libqt5-qtwebengine`.
|
||||
|
||||
On OpenBSD
|
||||
----------
|
||||
|
||||
qutebrowser is in http://cvsweb.openbsd.org/cgi-bin/cvsweb/ports/www/qutebrowser/[OpenBSD ports].
|
||||
|
||||
Install the package:
|
||||
|
||||
----
|
||||
# pkg_add qutebrowser
|
||||
----
|
||||
|
||||
Or alternatively, use the ports system :
|
||||
|
||||
----
|
||||
# cd /usr/ports/www/qutebrowser
|
||||
# make install
|
||||
----
|
||||
|
||||
On Windows
|
||||
----------
|
||||
|
||||
There are different ways to install qutebrowser on Windows:
|
||||
|
||||
Prebuilt binaries
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Prebuilt standalone packages and installers
|
||||
https://github.com/qutebrowser/qutebrowser/releases[are built] for every
|
||||
release.
|
||||
|
||||
Note that you'll need to upgrade to new versions manually (subscribe to the
|
||||
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser-announce[qutebrowser-announce
|
||||
mailinglist] to get notified on new releases). You can install a newer version
|
||||
without uninstalling the older one.
|
||||
|
||||
https://chocolatey.org/packages/qutebrowser[Chocolatey package]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* PackageManagement PowerShell module
|
||||
----
|
||||
PS C:\> Install-Package qutebrowser
|
||||
----
|
||||
* Chocolatey's client
|
||||
----
|
||||
C:\> choco install qutebrowser
|
||||
----
|
||||
|
||||
Manual install
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
* Use the installer from http://www.python.org/downloads[python.org] to get
|
||||
Python 3 (be sure to install pip).
|
||||
* Install https://testrun.org/tox/latest/index.html[tox] via
|
||||
https://pip.pypa.io/en/latest/[pip]:
|
||||
|
||||
----
|
||||
$ pip install tox
|
||||
----
|
||||
|
||||
Then <<tox,install qutebrowser via tox>>.
|
||||
|
||||
On macOS
|
||||
--------
|
||||
|
||||
Prebuilt binary
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
The easiest way to install qutebrowser on macOS is to use the prebuilt `.app`
|
||||
files from the
|
||||
https://github.com/qutebrowser/qutebrowser/releases[release page].
|
||||
|
||||
Note that you'll need to upgrade to new versions manually (subscribe to the
|
||||
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser-announce[qutebrowser-announce
|
||||
mailinglist] to get notified on new releases).
|
||||
|
||||
This binary is also available through the
|
||||
https://caskroom.github.io/[Homebrew Cask] package manager:
|
||||
|
||||
----
|
||||
$ brew cask install qutebrowser
|
||||
----
|
||||
|
||||
Manual Install
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Alternatively, you can install the dependencies via a package manager (like
|
||||
http://brew.sh/[Homebrew] or https://www.macports.org/[MacPorts]) and run
|
||||
qutebrowser from source.
|
||||
|
||||
==== Homebrew
|
||||
|
||||
----
|
||||
$ brew install qt5
|
||||
$ pip3 install qutebrowser
|
||||
----
|
||||
|
||||
Since the v1.0 release, qutebrowser uses QtWebEngine by default.
|
||||
|
||||
Homebrew's builds of Qt and PyQt don't come with QtWebKit (and `--with-qtwebkit`
|
||||
uses an old version of QtWebKit which qutebrowser doesn't support anymore). If
|
||||
you want QtWebKit support, you'll need to build an up-to-date QtWebKit
|
||||
https://github.com/annulen/webkit/wiki/Building-QtWebKit-on-OS-X[manually].
|
||||
|
||||
Packagers
|
||||
---------
|
||||
|
||||
There are example .desktop and icon files provided. They would go in the
|
||||
standard location for your distro (`/usr/share/applications` and
|
||||
`/usr/share/pixmaps` for example).
|
||||
|
||||
The normal `setup.py install` doesn't install these files, so you'll have to do
|
||||
it as part of the packaging process.
|
||||
|
||||
[[tox]]
|
||||
Installing qutebrowser with tox
|
||||
-------------------------------
|
||||
|
||||
Getting the repository
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
First of all, clone the repository using http://git-scm.org/[git] and switch
|
||||
into the repository folder:
|
||||
|
||||
----
|
||||
$ git clone https://github.com/qutebrowser/qutebrowser.git
|
||||
$ cd qutebrowser
|
||||
----
|
||||
|
||||
Installing depdendencies (including Qt)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Then run tox inside the qutebrowser repository to set up a
|
||||
https://docs.python.org/3/library/venv.html[virtual environment]:
|
||||
|
||||
----
|
||||
$ tox -e mkvenv-pypi
|
||||
----
|
||||
|
||||
This installs all needed Python dependencies in a `.venv` subfolder.
|
||||
|
||||
This comes with an up-to-date Qt/PyQt including QtWebEngine, but has a few
|
||||
caveats:
|
||||
|
||||
- Make sure your `python3` is Python 3.5 or newer, otherwise you'll get a "No
|
||||
matching distribution found" error. Note that qutebrowser itself also requires
|
||||
this.
|
||||
- It only works on 64-bit x86 systems, with other architectures you'll get the
|
||||
same error.
|
||||
- If your distribution uses OpenSSL 1.1 (like Debian Stretch or Archlinux),
|
||||
you'll need to set `LD_LIBRARY_PATH` to the OpenSSL 1.0 directory
|
||||
(`export LD_LIBRARY_PATH=/usr/lib/openssl-1.0` on Archlinux) before starting
|
||||
qutebrowser if you want SSL to work in certain downloads (e.g. for
|
||||
`:adblock-update` or `:download`).
|
||||
- It comes with a QtWebEngine compiled without proprietary codec support (such
|
||||
as h.264).
|
||||
|
||||
See the next section for an alternative.
|
||||
|
||||
Installing dependencies (system-wide Qt)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Alternatively, you can use `tox -e mkvenv` (without `-pypi`) to symlink your
|
||||
local Qt install instead of installing PyQt in the virtualenv. However, unless
|
||||
you have a new QtWebKit or QtWebEngine available, qutebrowser will not work. It
|
||||
also typically means you'll be using an older release of QtWebEngine.
|
||||
|
||||
On Windows, run `tox -e 'mkvenv-win' instead, however make sure that ONLY
|
||||
Python3 is in your PATH before running tox.
|
||||
|
||||
Creating a wrapper script
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can then create a simple wrapper script to start qutebrowser somewhere in
|
||||
your `$PATH` (e.g. `/usr/local/bin/qutebrowser` or `~/bin/qutebrowser`):
|
||||
|
||||
----
|
||||
#!/bin/bash
|
||||
~/path/to/qutebrowser/.venv/bin/python3 -m qutebrowser "$@"
|
||||
----
|
||||
|
||||
Updating
|
||||
~~~~~~~~
|
||||
|
||||
When you updated your local copy of the code (e.g. by pulling the git repo, or
|
||||
extracting a new version), the virtualenv should automatically use the updated
|
||||
code. However, if dependencies got added, this won't be reflected in the
|
||||
virtualenv. Thus it's recommended to run the following command to recreate the
|
||||
virtualenv:
|
||||
|
||||
----
|
||||
$ tox -r -e mkvenv-pypi
|
||||
----
|
||||
82
doc/notes
Normal file
@@ -0,0 +1,82 @@
|
||||
henk's thoughts
|
||||
===============
|
||||
|
||||
1. Power to the user! Protect privacy!
|
||||
Things the browser should only do with explicit consent from the user, if
|
||||
applicable the user should be able to choose which protocol/host/port triplets
|
||||
to white/blacklist:
|
||||
|
||||
- load/run executable code, like js, flash, java applets, ... (think NoScript)
|
||||
- requests to other domains, ports or using a different protocol than what the
|
||||
user requested (think RequestPolicy)
|
||||
- accept cookies
|
||||
- storing/saving/caching things, e.g. open tabs ("session"), cookies, page
|
||||
contents, browsing/download history, form data, ...
|
||||
- send referrer
|
||||
- disclose any (presence, type, version, settings, capabilities, etc.)
|
||||
information about OS, browser, installed fonts, plugins, addons, etc.
|
||||
|
||||
2. Be efficient!
|
||||
I tend to leave a lot of tabs open and nobody can deny that some websites
|
||||
simply suck, so the browser should, unless told otherwise by the user:
|
||||
|
||||
- load tabs only when needed
|
||||
- run code in tabs only when needed, i.e. when the tab is currently being
|
||||
used/viewed (background tabs doing some JS magic even when they are not being
|
||||
used can create a lot of unnecessary load on the machine)
|
||||
- finish requests to the domain the user requested (e.g. www.example.org)
|
||||
before doing any requests to other subdomains (e.g. images.example.org) and
|
||||
finish those before doing requests to thirdparty domains (e.g. example.com)
|
||||
|
||||
3. Be stable!
|
||||
- one site should not make the complete browser crash, only that site's tab
|
||||
|
||||
|
||||
Upstream Bugs
|
||||
=============
|
||||
|
||||
- Web inspector is blank unless .hide()/.show() is called.
|
||||
Asked on SO: http://stackoverflow.com/q/23499159/2085149
|
||||
TODO: Report to PyQt/Qt
|
||||
|
||||
- Report some other crashes
|
||||
|
||||
|
||||
/u/angelic_sedition's thoughts
|
||||
==============================
|
||||
|
||||
Well support for greasemonkey scripts and bookmarklets/js (which was mentioned
|
||||
in the arch forum post) would be a big addition. What I've usually missed when
|
||||
using other vim-like browsers is things that allow for different settings and
|
||||
key bindings for different contexts. With that implemented I think I could
|
||||
switch to a lightweight browser (and believe me, I'd like to) for the most part
|
||||
and only use firefox when I needed downthemall or something.
|
||||
|
||||
For example, I have different bindings based on tab position that are reloaded
|
||||
with a pentadactyl autocmd so that <space><homerow keys> will take me to tab
|
||||
1-10 if I'm in that range or 2-20 if I'm in that range. I have an autocmd that
|
||||
will run on completed downloads that passes the file path to a script that will
|
||||
open ranger in a floating window with that file cut (this is basically like
|
||||
using ranger to save files instead of the crappy gui popup).
|
||||
|
||||
I also have a few bindings based on tabgroups. Tabgroups are a firefox feature,
|
||||
but I find them very useful for sorting things by topic so that only the tabs
|
||||
I'm interested at the moment are visible.
|
||||
|
||||
Pentadactyl has a feature it calls groups. You can create a group that will
|
||||
activate for sites/urls that match a pattern with some regex support. This
|
||||
allows me, for example, to set up different (more convenient) bindings for
|
||||
zooming only on images. I'll never need use the equivalent of vim n (next text
|
||||
search match), so I can bind that to zoom. This allows setting up custom
|
||||
quickmarks/gotos using the same keys for different websites. For example, on
|
||||
reddit I have different g(some key) bindings to go to different subreddits.
|
||||
This can also be used to pass certain keys directly to the site (e.g. for use
|
||||
with RES). For sites that don't have modifiable bindings, I can use this with
|
||||
pentadactyl's feedkeys or xdotool to create my own custom bindings. I even have
|
||||
a binding that will call out to bash script with different arguments depending
|
||||
on the site to download an image or an image gallery depending on the site (in
|
||||
some cases passing the url to some cli program).
|
||||
|
||||
I've also noticed the lack of completion. For example, on "o" pentadactyl will
|
||||
show sites (e.g. from history) that can be completed. I think I've been spoiled
|
||||
by pentadactyl having completion for just about everything.
|
||||
@@ -5,36 +5,18 @@ The Compiler <mail@qutebrowser.org>
|
||||
NOTE: This page will only appear on the first start. To view it at a later
|
||||
time, use the `:help` command.
|
||||
|
||||
Basic keybindings to get you started
|
||||
------------------------------------
|
||||
|
||||
* Use the arrow keys or `hjkl` to move around a webpage (vim-like syntax is used in quite a few places)
|
||||
* To go to a new webpage, press `o`, then type a url, then press Enter (Use `O` to open the url in a new tab, `go` to edit the current URL)
|
||||
* If what you've typed isn't a url, then a search engine will be used instead (DuckDuckGo, by default)
|
||||
* To switch between tabs, use `J` (next tab) and `K` (previous tab), or press `<Alt-num>`, where `num` is the position of the tab to switch to
|
||||
* To close the current tab, press `d` (and press `u` to undo closing a tab)
|
||||
* Use `H` and `L` to go back and forth in the history
|
||||
* To click on something without using the mouse, press `f` to show the hints, then type the keys next to what you want to click on (if that sounds weird, then just try pressing `f` and see what happens)
|
||||
* Press `:` to show the commandline
|
||||
* To search in a page, press `/`, type the phrase to search for, then press Enter. Use `n` and `N` to go back and forth through the matches, and press Esc to stop doing the search.
|
||||
* To close qutebrowser, press `Alt-F4`, or `:q`, or `:wq` to save the currently open tabs and quit (note that in the settings you can make qutebrowser always save the currently open tabs)
|
||||
|
||||
What to do now
|
||||
--------------
|
||||
|
||||
* View the link:http://qutebrowser.org/img/cheatsheet-big.png[key binding cheatsheet]
|
||||
to make yourself familiar with the key bindings: +
|
||||
image:http://qutebrowser.org/img/cheatsheet-small.png["qutebrowser key binding cheatsheet",link="http://qutebrowser.org/img/cheatsheet-big.png"]
|
||||
* There's also a https://www.shortcutfoo.com/app/dojos/qutebrowser[free training
|
||||
course] on shortcutfoo for the keybindings - note that you need to be in
|
||||
insert mode (i) for it to work.
|
||||
* Run `:adblock-update` to download adblock lists and activate adblocking.
|
||||
* View the http://qutebrowser.org/img/cheatsheet-big.png[keybinding cheatsheet]
|
||||
to make yourself familiar with the keybindings: +
|
||||
image:http://qutebrowser.org/img/cheatsheet-small.png["qutebrowser keybinding cheatsheet",link="http://qutebrowser.org/img/cheatsheet-big.png"]
|
||||
* If you just cloned the repository, you'll need to run
|
||||
`scripts/asciidoc2html.py` to generate the documentation.
|
||||
* Go to the link:qute://settings[settings page] to set up qutebrowser the way you want it.
|
||||
* Subscribe to
|
||||
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser[the mailinglist] or
|
||||
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser-announce[the announce-only mailinglist].
|
||||
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!)
|
||||
improvements.
|
||||
|
||||
|
||||
@@ -7,24 +7,20 @@
|
||||
:man source: qutebrowser
|
||||
:man manual: qutebrowser manpage
|
||||
:toc:
|
||||
:homepage: https://www.qutebrowser.org/
|
||||
:homepage: http://www.qutebrowser.org/
|
||||
|
||||
== NAME
|
||||
qutebrowser - a keyboard-driven, vim-like browser based on PyQt5.
|
||||
qutebrowser - a keyboard-driven, vim-like browser based on PyQt5 and QtWebKit.
|
||||
|
||||
== SYNOPSIS
|
||||
*qutebrowser* ['-OPTION' ['...']] [':COMMAND' ['...']] ['URL' ['...']]
|
||||
|
||||
== DESCRIPTION
|
||||
qutebrowser is a keyboard-focused browser with a minimal GUI. It's based
|
||||
on Python and Qt5 and is free software, licensed under the GPL.
|
||||
qutebrowser is a keyboard-focused browser with with a minimal GUI. It's based
|
||||
on Python, PyQt5 and QtWebKit and free software, licensed under the GPL.
|
||||
|
||||
It was inspired by other browsers/addons like dwb and Vimperator/Pentadactyl.
|
||||
|
||||
Note the commands and settings of qutebrowser are not described in this
|
||||
manpage, but in the help integrated in qutebrowser - use the ":help" command to
|
||||
show it.
|
||||
|
||||
== OPTIONS
|
||||
// QUTE_OPTIONS_START
|
||||
=== positional arguments
|
||||
@@ -38,32 +34,14 @@ show it.
|
||||
*-h*, *--help*::
|
||||
show this help message and exit
|
||||
|
||||
*--basedir* 'BASEDIR'::
|
||||
Base directory for all storage.
|
||||
*-c* 'CONFDIR', *--confdir* 'CONFDIR'::
|
||||
Set config directory (empty for no config storage)
|
||||
|
||||
*-V*, *--version*::
|
||||
Show version and quit.
|
||||
|
||||
*-s* 'OPTION' 'VALUE', *--set* 'OPTION' 'VALUE'::
|
||||
Set a temporary setting for this session.
|
||||
|
||||
*-r* 'SESSION', *--restore* 'SESSION'::
|
||||
Restore a named session.
|
||||
|
||||
*-R*, *--override-restore*::
|
||||
Don't restore a session even if one would be restored.
|
||||
|
||||
*--target* '{auto,tab,tab-bg,tab-silent,tab-bg-silent,window}'::
|
||||
How URLs should be opened if there is already a qutebrowser instance running.
|
||||
|
||||
*--backend* '{webkit,webengine}'::
|
||||
Which backend to use.
|
||||
|
||||
*--enable-webengine-inspector*::
|
||||
Enable the web inspector for QtWebEngine. Note that this is a SECURITY RISK and you should not visit untrusted websites with the inspector turned on. See https://bugreports.qt.io/browse/QTBUG-50725 for more details.
|
||||
|
||||
=== debug arguments
|
||||
*-l* '{critical,error,warning,info,debug,vdebug}', *--loglevel* '{critical,error,warning,info,debug,vdebug}'::
|
||||
*-l* 'LOGLEVEL', *--loglevel* 'LOGLEVEL'::
|
||||
Set loglevel
|
||||
|
||||
*--logfilter* 'LOGFILTER'::
|
||||
@@ -75,50 +53,47 @@ show it.
|
||||
*--debug*::
|
||||
Turn on debugging options.
|
||||
|
||||
*--json-logging*::
|
||||
Output log lines in JSON format (one object per line).
|
||||
|
||||
*--nocolor*::
|
||||
Turn off colored logging.
|
||||
|
||||
*--force-color*::
|
||||
Force colored logging
|
||||
*--harfbuzz* '{old,new,system,auto}'::
|
||||
HarfBuzz engine version to use. Default: auto.
|
||||
|
||||
*--nowindow*::
|
||||
Don't show the main window.
|
||||
|
||||
*--temp-basedir*::
|
||||
Use a temporary basedir.
|
||||
*--debug-exit*::
|
||||
Turn on debugging of late exit.
|
||||
|
||||
*--no-err-windows*::
|
||||
Don't show any error windows (used for tests/smoke.py).
|
||||
*--no-crash-dialog*::
|
||||
Don't show a crash dialog.
|
||||
|
||||
*--qt-arg* 'NAME' 'VALUE'::
|
||||
Pass an argument with a value to Qt. For example, you can do `--qt-arg geometry 650x555+200+300` to set the window geometry.
|
||||
*--qt-style* 'STYLE'::
|
||||
Set the Qt GUI style to use.
|
||||
|
||||
*--qt-flag* 'QT_FLAG'::
|
||||
Pass an argument to Qt as flag.
|
||||
*--qt-stylesheet* 'STYLESHEET'::
|
||||
Override the Qt application stylesheet.
|
||||
|
||||
*--debug-flag* 'DEBUG_FLAGS'::
|
||||
Pass name of debugging feature to be turned on.
|
||||
*--qt-widgetcount*::
|
||||
Print debug message at the end about number of widgets left undestroyed and maximum number of widgets existed at the same time.
|
||||
|
||||
*--qt-reverse*::
|
||||
Set the application's layout direction to right-to-left.
|
||||
|
||||
*--qt-qmljsdebugger* 'port:PORT[,block]'::
|
||||
Activate the QML/JS debugger with a specified port. 'block' is optional and will make the application wait until a debugger connects to it.
|
||||
// QUTE_OPTIONS_END
|
||||
|
||||
== FILES
|
||||
|
||||
- '~/.config/qutebrowser/config.py': Configuration file.
|
||||
- '~/.config/qutebrowser/autoconfig.yml': Configuration done via the GUI.
|
||||
- '~/.config/qutebrowser/qutebrowser.conf': Main config file.
|
||||
- '~/.config/qutebrowser/quickmarks': Saved quickmarks.
|
||||
- '~/.local/share/qutebrowser/': Various state information.
|
||||
- '~/.cache/qutebrowser/': Temporary data.
|
||||
|
||||
Note qutebrowser conforms to the XDG basedir specification - if
|
||||
'XDG_CONFIG_HOME', 'XDG_DATA_HOME' or 'XDG_CACHE_HOME' are set in the
|
||||
environment, the directories configured there are used instead of the above
|
||||
defaults.
|
||||
- '~/.config/qutebrowser/keys.conf': Defined keybindings.
|
||||
- '~/.local/share/qutebrowser/': Various state information
|
||||
|
||||
== BUGS
|
||||
Bugs are tracked in the Github issue tracker at
|
||||
https://github.com/qutebrowser/qutebrowser/issues.
|
||||
https://github.com/The-Compiler/qutebrowser/issues.
|
||||
|
||||
If you found a bug, use the built-in ':report' command to create a bug report
|
||||
with all information needed.
|
||||
@@ -128,7 +103,7 @@ https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser[mailinglist] at
|
||||
mailto:qutebrowser@lists.qutebrowser.org[] instead.
|
||||
|
||||
For security bugs, please contact me directly at me@the-compiler.org, GPG ID
|
||||
https://www.the-compiler.org/pubkey.asc[0xFD55A072].
|
||||
http://www.the-compiler.org/pubkey.asc[0xFD55A072].
|
||||
|
||||
== COPYRIGHT
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
@@ -144,14 +119,12 @@ You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
== RESOURCES
|
||||
* Website: https://www.qutebrowser.org/
|
||||
* Website: http://www.qutebrowser.org/
|
||||
* Mailinglist: mailto:qutebrowser@lists.qutebrowser.org[] /
|
||||
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser
|
||||
* Announce-only mailinglist: mailto:qutebrowser-announce@lists.qutebrowser.org[] /
|
||||
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser-announce
|
||||
* IRC: irc://irc.freenode.org/#qutebrowser[`#qutebrowser`] on
|
||||
http://freenode.net/[Freenode]
|
||||
* Github: https://github.com/qutebrowser/qutebrowser
|
||||
* Github: https://github.com/The-Compiler/qutebrowser
|
||||
|
||||
== AUTHOR
|
||||
*qutebrowser* was written by Florian Bruhin. All contributors can be found in
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
Getting stacktraces on crashes
|
||||
==============================
|
||||
:toc:
|
||||
The Compiler <mail@qutebrowser.org>
|
||||
|
||||
When there is a fatal crash in qutebrowser - most of the times a
|
||||
@@ -15,17 +14,10 @@ https://en.wikipedia.org/wiki/Debug_symbol[debugging symbols] is required.
|
||||
The rest of this guide is quite Linux specific, though there is a
|
||||
<<windows,section for Windows>> at the end.
|
||||
|
||||
Crashes which can be reproduced
|
||||
-------------------------------
|
||||
|
||||
If a crash can be reproduced, packages with debugging symbols should be
|
||||
installed, and the crash should be reproduced under gdb.
|
||||
|
||||
Getting debugging symbols
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
-------------------------
|
||||
|
||||
Debian/Ubuntu/...
|
||||
^^^^^^^^^^^^^^^^^
|
||||
.Debian/Ubuntu/...
|
||||
|
||||
For Debian based systems (Debian, Ubuntu, Linux Mint, ...), debug information
|
||||
is available in the repositories:
|
||||
@@ -34,71 +26,76 @@ is available in the repositories:
|
||||
# apt-get install python3-pyqt5-dbg python3-pyqt5.qtwebkit-dbg python3-dbg libqt5webkit5-dbg
|
||||
----
|
||||
|
||||
Archlinux
|
||||
^^^^^^^^^
|
||||
.Archlinux
|
||||
|
||||
For Archlinux, no debug informations are provided. You can either compile Qt
|
||||
yourself (which will take a few hours even on a modern machine) or use
|
||||
debugging symbols compiled/packaged by me (x86_64 only).
|
||||
debugging symbols compiled by me (x86_64 only).
|
||||
|
||||
To install my pre-built packages
|
||||
++++++++++++++++++++++++++++++++
|
||||
|
||||
First download and sign the key:
|
||||
To compile by yourself:
|
||||
|
||||
----
|
||||
# pacman-key -r 0xD6A1C70FE80A0C82
|
||||
$ pacman-key -f 0xD6A1C70FE80A0C82
|
||||
Key fingerprint = 14AF EC28 70C6 4863 C5C7 ACCB D6A1 C70F E80A 0C82
|
||||
# pacman-key --lsign-key 0xD6A1C70FE80A0C82
|
||||
----
|
||||
|
||||
Then edit your `/etc/pacman.conf` to add the repository to the bottom:
|
||||
|
||||
----
|
||||
[qt-debug]
|
||||
Server = http://qutebrowser.org/qt-debug/$arch
|
||||
----
|
||||
|
||||
Then install the packages:
|
||||
|
||||
----
|
||||
# pacman -Suy pyqt5-common-debug python-pyqt5-debug qt5-base-debug qt5-webkit-debug qt5-webengine-debug
|
||||
----
|
||||
|
||||
The `-debug` packages conflict with the non-debug variants - it's safe to
|
||||
remove them.
|
||||
|
||||
To compile by yourself
|
||||
++++++++++++++++++++++
|
||||
|
||||
Note that building Qt will likely take multiple hours, even on a recent system.
|
||||
I'd also expect it to take around 6 GB of RAM and 30 GB of disk space for a
|
||||
successful compile run.
|
||||
|
||||
----
|
||||
$ git clone https://github.com/qutebrowser/qt-debug-pkgbuild.git
|
||||
$ git clone https://github.com/The-Compiler/qt-debug-pkgbuild.git
|
||||
$ cd qt-debug-pkgbuild
|
||||
$ export DEBUG_CFLAGS='-ggdb3 -fvar-tracking-assignments -Og'
|
||||
$ export DEBUG_CXXFLAGS='-ggdb3 -fvar-tracking-assignments -Og'
|
||||
$ git checkout symbols
|
||||
$ cd qt5
|
||||
$ makepkg -si --pkg qt5-base-debug,qt5-webkit-debug,qt5-webengine-debug
|
||||
$ makepkg -si
|
||||
$ cd ../pyqt5
|
||||
$ makepkg -si --pkg pyqt5-common-debug,python-pyqt5-debug
|
||||
$ makepkg -si
|
||||
----
|
||||
|
||||
Getting the stack trace
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
First install `gdb` on your system if it's not installed already.
|
||||
|
||||
Then run qutebrowser directly inside gdb like this:
|
||||
To install my pre-built packages:
|
||||
|
||||
----
|
||||
$ gdb $(readlink -f $(which python3)) -ex 'run -m qutebrowser --debug'
|
||||
$ mkdir qt-debug
|
||||
$ cd qt-debug
|
||||
$ wget -r -l1 -A '*.tar.xz' -L -np -nd http://www.qutebrowser.org/qt-symbols-pkg/
|
||||
# pacman -U *.pkg.tar.xz
|
||||
----
|
||||
|
||||
After you reproduce the crash, you should now see something like:
|
||||
After you are done debugging, make sure to install the system packages again so
|
||||
you get updates. This can be done with this command:
|
||||
|
||||
----
|
||||
# pacman -S qt5
|
||||
----
|
||||
|
||||
Getting a core dump
|
||||
-------------------
|
||||
|
||||
The next step is finding the core dump so we can get a stacktrace from it.
|
||||
|
||||
First of all, try to reproduce your problem. If you can, run qutebrowser
|
||||
directly inside gdb like this:
|
||||
|
||||
----
|
||||
$ gdb $(which python3) -ex 'run -m qutebrowser --debug'
|
||||
----
|
||||
|
||||
If you cannot reproduce the problem, you need to check if a coredump got
|
||||
written somewhere.
|
||||
|
||||
Check the file `/proc/sys/kernel/core_pattern` on your system. If it does not
|
||||
start with a `|` character (pipe), check if there is a file named `core` or
|
||||
`core.NNNN` in the directory from that file, or in the current directory.
|
||||
|
||||
If so, execute gdb like this:
|
||||
|
||||
----
|
||||
$ gdb $(which python3) /path/to/core
|
||||
----
|
||||
|
||||
If your `/proc/sys/kernel/core_pattern` contains something like
|
||||
`|/usr/lib/systemd/systemd-coredump`, use `coredumpctl` as root to run gdb:
|
||||
|
||||
----
|
||||
# coredumpctl gdb $(which python3)
|
||||
----
|
||||
|
||||
Getting a stack trace
|
||||
---------------------
|
||||
|
||||
Regardless of the way you used to open gdb, you should now see something like:
|
||||
|
||||
----
|
||||
Program received signal SIGSEGV, Segmentation fault.
|
||||
@@ -110,58 +107,16 @@ Now enter these commands at the gdb prompt:
|
||||
|
||||
----
|
||||
(gdb) set logging on
|
||||
(gdb) bt full
|
||||
# you might have to press enter a few times until you get the prompt back
|
||||
(gdb) quit
|
||||
----
|
||||
|
||||
This will create a `gdb.txt` in your current directory.
|
||||
|
||||
Copy the last few lines of the debug log (before you got the gdb prompt) and
|
||||
the full content of `gdb.txt` into the bug report. Please also add some words
|
||||
about what you were doing (or what pages you visited) before the crash
|
||||
happened.
|
||||
|
||||
Crashes which can NOT be reproduced
|
||||
-----------------------------------
|
||||
|
||||
If you cannot reproduce the problem, you need to check if a coredump got
|
||||
written somewhere. You should not install debug symbols as they won't match the
|
||||
generated coredump.
|
||||
|
||||
First install `gdb` on your system if it's not installed already.
|
||||
|
||||
Then check the file `/proc/sys/kernel/core_pattern` on your system. If it does
|
||||
not start with a `|` character (pipe), check if there is a file named `core` or
|
||||
`core.NNNN` in the directory from that file, or in the current directory.
|
||||
|
||||
If so, execute gdb like this:
|
||||
|
||||
----
|
||||
$ gdb $(readlink -f $(which python3)) /path/to/core
|
||||
----
|
||||
|
||||
If your `/proc/sys/kernel/core_pattern` contains something like
|
||||
`|/usr/lib/systemd/systemd-coredump`, use `coredumpctl` to run gdb:
|
||||
|
||||
----
|
||||
$ coredumpctl gdb $(readlink -f $(which python3))
|
||||
----
|
||||
|
||||
Getting the stack trace
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Now enter these commands at the gdb prompt:
|
||||
|
||||
----
|
||||
(gdb) set logging on
|
||||
(gdb) set logging redirect on
|
||||
(gdb) bt
|
||||
# you might have to press enter a few times until you get the prompt back
|
||||
(gdb) set logging redirect off
|
||||
(gdb) quit
|
||||
----
|
||||
|
||||
Copy the content of `gdb.txt` into the bug report. Please also add some words
|
||||
about what you were doing (or what pages you visited) before the crash
|
||||
Now copy the last few lines of the debug log (before you got the gdb prompt)
|
||||
and the full content of `gdb.txt` into the bug report. Please also add some
|
||||
words about what you were doing (or what pages you visited) before the crash
|
||||
happened.
|
||||
|
||||
[[windows]]
|
||||
@@ -174,10 +129,10 @@ When you see the _qutebrowser.exe has stopped working_ window, do not click
|
||||
file displayed there.
|
||||
|
||||
Now install
|
||||
https://www.microsoft.com/en-us/download/details.aspx?id=49924[DebugDiag] from
|
||||
Microsoft, then run the *DebugDiag 2 Analysis* tool. There, check
|
||||
*CrashHangAnalysis* and add your crash dump via *Add Data files*. Then click
|
||||
*Start analysis*.
|
||||
http://www.microsoft.com/en-us/download/details.aspx?id=42933[DebugDiag] from
|
||||
Microsoft, then run the "DebugDiag 2 Analysis" tool. There, check
|
||||
"CrashHangAnalysis" and add your crash dump via "Add Data files". Then click
|
||||
"Start analysis".
|
||||
|
||||
Close the Internet Explorer which opens when it's done and use the
|
||||
folder-button at the top left to get to the reports. There find the report file
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
Writing qutebrowser userscripts
|
||||
===============================
|
||||
The Compiler <mail@qutebrowser.org>
|
||||
|
||||
qutebrowser is extensible by writing userscripts which can be called via the
|
||||
`:spawn --userscript` command, or via a key binding.
|
||||
|
||||
You can also call a userscript via hints so they get the selected hint URL by
|
||||
calling `:hint links userscript ...`.
|
||||
|
||||
These userscripts are similar to the (non-javascript) dwb userscripts. They can
|
||||
be written in any language which can read environment variables and write to a
|
||||
FIFO. Note they are *not* related to Greasemonkey userscripts.
|
||||
|
||||
Note for simple things such as opening the current page with another browser or
|
||||
mpv, a simple key binding to something like `:spawn mpv {url}` should suffice.
|
||||
|
||||
Also note userscripts need to have the executable bit set (`chmod +x`) for
|
||||
qutebrowser to run them.
|
||||
|
||||
To call a userscript, it needs to be stored in your data directory under
|
||||
`userscripts` (for example: `~/.local/share/qutebrowser/userscripts/myscript`),
|
||||
or just use an absolute path.
|
||||
|
||||
NOTE: On Windows, only userscripts with `com`, `bat`, or `exe` extensions will be launched.
|
||||
|
||||
Getting information
|
||||
-------------------
|
||||
|
||||
The following environment variables will be set when a userscript is launched:
|
||||
|
||||
- `QUTE_MODE`: Either `hints` (started via hints) or `command` (started via
|
||||
command or key binding).
|
||||
- `QUTE_USER_AGENT`: The currently set user agent.
|
||||
- `QUTE_FIFO`: The FIFO or file to write commands to.
|
||||
- `QUTE_HTML`: Path of a file containing the HTML source of the current page.
|
||||
- `QUTE_TEXT`: Path of a file containing the plaintext of the current page.
|
||||
- `QUTE_CONFIG_DIR`: Path of the directory containing qutebrowser's configuration.
|
||||
- `QUTE_DATA_DIR`: Path of the directory containing qutebrowser's data.
|
||||
- `QUTE_DOWNLOAD_DIR`: Path of the downloads directory.
|
||||
- `QUTE_COMMANDLINE_TEXT`: Text currently in qutebrowser's command line.
|
||||
|
||||
In `command` mode:
|
||||
|
||||
- `QUTE_URL`: The current URL.
|
||||
- `QUTE_TITLE`: The title of the current page.
|
||||
- `QUTE_SELECTED_TEXT`: The text currently selected on the page.
|
||||
- `QUTE_SELECTED_HTML` The HTML currently selected on the page (not supported
|
||||
with QtWebEngine).
|
||||
|
||||
In `hints` mode:
|
||||
|
||||
- `QUTE_URL`: The URL selected via hints.
|
||||
- `QUTE_SELECTED_TEXT`: The plain text of the element selected via hints.
|
||||
- `QUTE_SELECTED_HTML` The HTML of the element selected via hints.
|
||||
|
||||
Sending commands
|
||||
----------------
|
||||
|
||||
Normal qutebrowser commands can be written to `$QUTE_FIFO` and will be
|
||||
executed.
|
||||
|
||||
On Unix/macOS, this is a named pipe and commands written to it will get executed
|
||||
immediately.
|
||||
|
||||
On Windows, this is a regular file, and the commands in it will be executed as
|
||||
soon as your userscript terminates. This means when writing multiple commands,
|
||||
you should append to the file (`>>` in bash) rather than overwrite it (`>`).
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Opening the currently selected word on http://www.dict.cc/[dict.cc]:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
#!/bin/bash
|
||||
|
||||
echo "open -t http://www.dict.cc/?s=$QUTE_SELECTED_TEXT" >> "$QUTE_FIFO"
|
||||
----
|
||||
|
||||
Libraries
|
||||
---------
|
||||
|
||||
Some third-party libraries are available to make writing userscripts easier:
|
||||
|
||||
- Python: https://github.com/hiway/python-qutescript[python-qutescript]
|
||||
- Node.js: https://www.npmjs.com/package/qutejs[qutejs]
|
||||
|
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 945 B After Width: | Height: | Size: 872 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 21 KiB |
@@ -1,207 +0,0 @@
|
||||
/* XPM */
|
||||
static char *qutebrowser[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"32 32 169 2 ",
|
||||
" c #0A396E",
|
||||
". c #0B3C72",
|
||||
"X c #0B4077",
|
||||
"o c #0C437B",
|
||||
"O c #134175",
|
||||
"+ c #15467C",
|
||||
"@ c #18477B",
|
||||
"# c #1A497D",
|
||||
"$ c #0D4B86",
|
||||
"% c #0F4E8D",
|
||||
"& c #124A80",
|
||||
"* c #1F4F83",
|
||||
"= c #0E518C",
|
||||
"- c #1F5084",
|
||||
"; c #11508C",
|
||||
": c #0F5193",
|
||||
"> c #115799",
|
||||
", c #115B9C",
|
||||
"< c #204F83",
|
||||
"1 c #245287",
|
||||
"2 c #2A598C",
|
||||
"3 c #325E8F",
|
||||
"4 c #11609F",
|
||||
"5 c #346496",
|
||||
"6 c #3B6898",
|
||||
"7 c #115CA1",
|
||||
"8 c #115EAC",
|
||||
"9 c #1263A3",
|
||||
"0 c #1260AD",
|
||||
"q c #136BAC",
|
||||
"w c #136BB2",
|
||||
"e c #1366BA",
|
||||
"r c #196BB2",
|
||||
"t c #157ABB",
|
||||
"y c #1577BB",
|
||||
"u c #2E6DB0",
|
||||
"i c #387FB1",
|
||||
"p c #456E9A",
|
||||
"a c #4873A1",
|
||||
"s c #4375AA",
|
||||
"d c #507AA6",
|
||||
"f c #597EA4",
|
||||
"g c #4D7EB3",
|
||||
"h c #156FCB",
|
||||
"j c #167AC5",
|
||||
"k c #1675CA",
|
||||
"l c #177BCE",
|
||||
"z c #1777D8",
|
||||
"x c #1476E4",
|
||||
"c c #167BE6",
|
||||
"v c #167DE8",
|
||||
"b c #197EEF",
|
||||
"n c #1A7FF0",
|
||||
"m c #1A80BE",
|
||||
"M c #5F87AF",
|
||||
"N c #5D8BBA",
|
||||
"B c #5A84B1",
|
||||
"V c #6C8FB3",
|
||||
"C c #6F96BE",
|
||||
"Z c #1886CC",
|
||||
"A c #1883D7",
|
||||
"S c #198DD5",
|
||||
"D c #1987D9",
|
||||
"F c #198ADC",
|
||||
"G c #1A96DC",
|
||||
"H c #3090D9",
|
||||
"J c #1682E9",
|
||||
"K c #1983ED",
|
||||
"L c #1689E9",
|
||||
"P c #1A8DEE",
|
||||
"I c #1B95ED",
|
||||
"U c #1C9EEA",
|
||||
"Y c #1B97E4",
|
||||
"T c #1A84F2",
|
||||
"R c #1A8BF2",
|
||||
"E c #1C94F4",
|
||||
"W c #1D9CF5",
|
||||
"Q c #3388E6",
|
||||
"! c #3D90E9",
|
||||
"~ c #228EF3",
|
||||
"^ c #229FF6",
|
||||
"/ c #3294F4",
|
||||
"( c #3D9FF6",
|
||||
") c #339CF4",
|
||||
"_ c #1CA2E5",
|
||||
"` c #1DABEE",
|
||||
"' c #1DA4F6",
|
||||
"] c #1EA9F7",
|
||||
"[ c #1EADF8",
|
||||
"{ c #1FB4F9",
|
||||
"} c #1FB9FA",
|
||||
"| c #20ACF8",
|
||||
" . c #27A4F6",
|
||||
".. c #3DA9F6",
|
||||
"X. c #20B9FA",
|
||||
"o. c #2EB6F9",
|
||||
"O. c #458DC9",
|
||||
"+. c #5C8DC1",
|
||||
"@. c #5795C6",
|
||||
"#. c #709DCB",
|
||||
"$. c #74A8DD",
|
||||
"%. c #4A97EA",
|
||||
"&. c #4896EA",
|
||||
"*. c #559EEA",
|
||||
"=. c #439AF5",
|
||||
"-. c #46A3F6",
|
||||
";. c #5FA9F6",
|
||||
":. c #5EA6F3",
|
||||
">. c #47BCF9",
|
||||
",. c #51B5F8",
|
||||
"<. c #58BDF8",
|
||||
"1. c #68ABEF",
|
||||
"2. c #7DB9E7",
|
||||
"3. c #63AEF7",
|
||||
"4. c #6FB1F7",
|
||||
"5. c #66B9F8",
|
||||
"6. c #61B2F6",
|
||||
"7. c #71B4F7",
|
||||
"8. c #78B7F4",
|
||||
"9. c #72BFF9",
|
||||
"0. c #3BC0FA",
|
||||
"q. c #6FCEFB",
|
||||
"w. c #6CC5FA",
|
||||
"e. c #7BCAF9",
|
||||
"r. c #89A7C3",
|
||||
"t. c #83A2C1",
|
||||
"y. c #98B6D3",
|
||||
"u. c #9DB9D3",
|
||||
"i. c #89B6E4",
|
||||
"p. c #83B6E9",
|
||||
"a. c #81BDF7",
|
||||
"s. c #83BFF8",
|
||||
"d. c #9EC4E9",
|
||||
"f. c #8CC2F9",
|
||||
"g. c #85CDFB",
|
||||
"h. c #87C4F9",
|
||||
"j. c #92C6F9",
|
||||
"k. c #95CAFA",
|
||||
"l. c #9CCBFA",
|
||||
"z. c #89D7FC",
|
||||
"x. c #91D9FC",
|
||||
"c. c #9CDEFD",
|
||||
"v. c #9ED2FB",
|
||||
"b. c #A7CAEC",
|
||||
"n. c #B5CEE3",
|
||||
"m. c #A1CEFA",
|
||||
"M. c #AED0F0",
|
||||
"N. c #ACD6FA",
|
||||
"B. c #A0DFFC",
|
||||
"V. c #AFD8FC",
|
||||
"C. c #B5D9FB",
|
||||
"Z. c #BCDDFC",
|
||||
"A. c #BFDCF5",
|
||||
"S. c #ACE3FD",
|
||||
"D. c #B5E5FE",
|
||||
"F. c #BBE2FC",
|
||||
"G. c #CFE5F5",
|
||||
"H. c #C3E1FC",
|
||||
"J. c #CAE6FD",
|
||||
"K. c #CCEBFD",
|
||||
"L. c #C4EBFE",
|
||||
"P. c #D6EDFE",
|
||||
"I. c #DAEEFD",
|
||||
"U. c #DEF1FE",
|
||||
"Y. c #D6F2FE",
|
||||
"T. c #E4F4FE",
|
||||
"R. c #E9F6FE",
|
||||
"E. c #EBF8FF",
|
||||
"W. c None",
|
||||
/* pixels */
|
||||
"W.W.W.W.W.W.W.W.W.W.W.c.S.L.Y.E.E.S.X.} W.W.W.W.W.W.W.W.W.W.W.W.",
|
||||
"W.W.W.W.W.W.W.W.W.D.T.E.E.T.L.D.c.z.} } X.} } W.W.W.W.W.W.W.W.W.",
|
||||
"W.W.W.W.W.W.W.B.T.T.R.T.R.U.0.X.z.S.} } } } { { X.W.W.W.W.W.W.W.",
|
||||
"W.W.W.W.W.W.x.x.K.T.T.T.L.P.q.o.{ } } ` _ { { { { { W.W.W.W.W.W.",
|
||||
"W.W.W.W.W.c.P.D.G.u.r.i 9 Z _ { { G 4 X t { { { { { { W.W.W.W.W.",
|
||||
"W.W.W.W.K.U.n.f O { = t { { { { [ { { W.W.W.W.",
|
||||
"W.W.W.F.I.t.. ' t { { [ [ [ [ [ >.W.W.W.",
|
||||
"W.W.x.P.V ' X t ` [ [ [ [ [ [ o.e.W.W.",
|
||||
"W.W.J.y. X t S Y Z $ ' . y [ [ [ ] [ [ | Z.J.W.W.",
|
||||
"W.<.e.& , _ ] ] [ ] U . ' . y [ ' [ ] ] ] w.K.J.g.W.",
|
||||
"W.' S o ' ' [ ' [ ' ] o ' . y Y 9 = = 9 @.J.J.J.F.W.",
|
||||
"W.| , j ' ' ' ' ' ' ' o ' . $ p A.J.J.g.",
|
||||
"' .. G ' ' ' ' ' ' ' o ' . M H.H.h.",
|
||||
",.2. . W ' W ' ' ' ' W . ' . M.A.x.",
|
||||
"N.M.. . W W W ' W W W W .w 9 I U 0 #.Z.m.",
|
||||
" .9.O D W W W W ' W j $ % F W W W .5 d Z.C.",
|
||||
"W W ; 9 9.h.5...Q % o j W W W W W W O. 3 C.N.",
|
||||
"E W 7 B b.d.a . w E E W W W E W E A @ C.l.",
|
||||
"I E l u W E W E W E E E E A . - k.6.",
|
||||
"P E E 7 m.o E E E E E E E E l . = E P ",
|
||||
"L E E E > . O s.o E E E E E E E E 7 , E L ",
|
||||
"W.R E R ) #.5 1 6 N i.2 s.+ E E E E E E R L . k R W.",
|
||||
"W.L R E -.m.m.m.m.m.m.2 m.@ N m.m.s.( R R % X E J W.",
|
||||
"W.W.K R ~ a.m.l.l.l.l.2 s.+ < i.l.m.j.h % e K W.W.",
|
||||
"W.W.J R R / l.l.l.l.k.2 s.+ * 5 + 8 R J W.W.",
|
||||
"W.W.W.v T R 3.k.k.j.k.2 2 j.& . 8 R v W.W.W.",
|
||||
"W.W.W.W.J T ~ 7.j.j.j.g +.p.j.s.+. . . : z T v W.W.W.W.",
|
||||
"W.W.W.W.W.c T T =.f.j.j.s.j.j.j.j.$.g s u e h b T T v W.W.W.W.W.",
|
||||
"W.W.W.W.W.W.c b n 4.f.f.s.m.s.s.s.j.s.j./ T n T b c W.W.W.W.W.W.",
|
||||
"W.W.W.W.W.W.W.c x 1.s.s.s.s.s.s.s.s.4.=.n T n c c W.W.W.W.W.W.W.",
|
||||
"W.W.W.W.W.W.W.W.W.&.*.1.a.s.s.s.s.3.n n v x x W.W.W.W.W.W.W.W.W.",
|
||||
"W.W.W.W.W.W.W.W.W.W.W.%.%.%.%.*.*.Q x x x W.W.W.W.W.W.W.W.W.W.W."
|
||||
};
|
||||
@@ -29,8 +29,6 @@ profile qutebrowser /usr/{local/,}bin/qutebrowser {
|
||||
|
||||
/proc/*/mounts r,
|
||||
owner /tmp/** rwkl,
|
||||
owner /run/user/*/ rw,
|
||||
owner /run/user/*/** krw,
|
||||
|
||||
@{HOME}/.config/qutebrowser/** krw,
|
||||
@{HOME}/.local/share/qutebrowser/** krw,
|
||||
|
||||
4254
misc/cheatsheet.svg
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 135 KiB |
@@ -1,77 +0,0 @@
|
||||
Name "qutebrowser"
|
||||
|
||||
Unicode true
|
||||
RequestExecutionLevel admin
|
||||
SetCompressor /solid lzma
|
||||
|
||||
!ifdef X64
|
||||
OutFile "..\dist\qutebrowser-${VERSION}-amd64.exe"
|
||||
InstallDir "$ProgramFiles64\qutebrowser"
|
||||
!else
|
||||
OutFile "..\dist\qutebrowser-${VERSION}-win32.exe"
|
||||
InstallDir "$ProgramFiles\qutebrowser"
|
||||
!endif
|
||||
|
||||
;Default installation folder
|
||||
|
||||
!include "MUI2.nsh"
|
||||
;!include "MultiUser.nsh"
|
||||
|
||||
!define MUI_ABORTWARNING
|
||||
;!define MULTIUSER_MUI
|
||||
;!define MULTIUSER_INSTALLMODE_COMMANDLINE
|
||||
!define MUI_ICON "../icons/qutebrowser.ico"
|
||||
!define MUI_UNICON "../icons/qutebrowser.ico"
|
||||
|
||||
!insertmacro MUI_PAGE_LICENSE "..\LICENSE"
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
; depends on admin status
|
||||
;SetShellVarContext current
|
||||
|
||||
|
||||
Section "Install"
|
||||
|
||||
; Uninstall old versions
|
||||
ExecWait 'MsiExec.exe /quiet /qn /norestart /X{633F41F9-FE9B-42D1-9CC4-718CBD01EE11}'
|
||||
ExecWait 'MsiExec.exe /quiet /qn /norestart /X{9331D947-AC86-4542-A755-A833429C6E69}'
|
||||
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
!ifdef X64
|
||||
file /r "..\dist\qutebrowser-${VERSION}-x64\*.*"
|
||||
!else
|
||||
file /r "..\dist\qutebrowser-${VERSION}-x86\*.*"
|
||||
!endif
|
||||
|
||||
SetShellVarContext all
|
||||
CreateShortCut "$SMPROGRAMS\qutebrowser.lnk" "$INSTDIR\qutebrowser.exe"
|
||||
|
||||
;Create uninstaller
|
||||
WriteUninstaller "$INSTDIR\uninst.exe"
|
||||
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qutebrowser" "DisplayName" "qutebrowser"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qutebrowser" "UninstallString" '"$INSTDIR\uninst.exe"'
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qutebrowser" "QuietUninstallString" '"$INSTDIR\uninst.exe" /S'
|
||||
|
||||
SectionEnd
|
||||
|
||||
;--------------------------------
|
||||
;Uninstaller Section
|
||||
|
||||
Section "Uninstall"
|
||||
|
||||
SetShellVarContext all
|
||||
Delete "$SMPROGRAMS\qutebrowser.lnk"
|
||||
|
||||
RMDir /r "$INSTDIR\*.*"
|
||||
RMDir "$INSTDIR"
|
||||
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qutebrowser"
|
||||
|
||||
SectionEnd
|
||||
@@ -1,75 +0,0 @@
|
||||
# -*- mode: python -*-
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
sys.path.insert(0, os.getcwd())
|
||||
from scripts import setupcommon
|
||||
|
||||
block_cipher = None
|
||||
|
||||
|
||||
def get_data_files():
|
||||
data_files = [
|
||||
('../qutebrowser/html', 'html'),
|
||||
('../qutebrowser/img', 'img'),
|
||||
('../qutebrowser/javascript', 'javascript'),
|
||||
('../qutebrowser/html/doc', 'html/doc'),
|
||||
('../qutebrowser/git-commit-id', ''),
|
||||
('../qutebrowser/config/configdata.yml', 'config'),
|
||||
]
|
||||
|
||||
# if os.path.exists(os.path.join('qutebrowser', '3rdparty', 'pdfjs')):
|
||||
# data_files.append(('../qutebrowser/3rdparty/pdfjs', '3rdparty/pdfjs'))
|
||||
# else:
|
||||
# print("Warning: excluding pdfjs as it's not present!")
|
||||
|
||||
return data_files
|
||||
|
||||
|
||||
setupcommon.write_git_file()
|
||||
|
||||
|
||||
if os.name == 'nt':
|
||||
icon = 'icons/qutebrowser.ico'
|
||||
elif sys.platform == 'darwin':
|
||||
icon = 'icons/qutebrowser.icns'
|
||||
else:
|
||||
icon = None
|
||||
|
||||
|
||||
a = Analysis(['../qutebrowser/__main__.py'],
|
||||
pathex=['misc'],
|
||||
binaries=None,
|
||||
datas=get_data_files(),
|
||||
hiddenimports=['PyQt5.QtOpenGL', 'PyQt5._QOpenGLFunctions_2_0'],
|
||||
hookspath=[],
|
||||
runtime_hooks=[],
|
||||
excludes=['tkinter'],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher)
|
||||
pyz = PYZ(a.pure, a.zipped_data,
|
||||
cipher=block_cipher)
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
exclude_binaries=True,
|
||||
name='qutebrowser',
|
||||
icon=icon,
|
||||
debug=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
console=False )
|
||||
coll = COLLECT(exe,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
strip=False,
|
||||
upx=True,
|
||||
name='qutebrowser')
|
||||
|
||||
app = BUNDLE(coll,
|
||||
name='qutebrowser.app',
|
||||
icon=icon,
|
||||
# https://github.com/pyinstaller/pyinstaller/blob/b78bfe530cdc2904f65ce098bdf2de08c9037abb/PyInstaller/hooks/hook-PyQt5.QtWebEngineWidgets.py#L24
|
||||
bundle_identifier='org.qt-project.Qt.QtWebEngineCore')
|
||||
@@ -1,20 +0,0 @@
|
||||
This directory contains various `requirements` files which are used by `tox` to
|
||||
have reproducable tests with pinned versions.
|
||||
|
||||
The files are generated based on unpinned requirements in `*.txt-raw` files.
|
||||
|
||||
Those files can also contain some special commands:
|
||||
|
||||
- Add an additional comment to a line: `#@ comment: <package> <comment here>`
|
||||
- Filter a line for requirements.io: `#@ filter: <package> <filter>`
|
||||
- Don't include a package in the output: `#@ ignore: <package>` (or multiple packages)
|
||||
- Replace a part of a frozen package specification with another: `#@ replace <regex> <replacement>`
|
||||
|
||||
Some examples:
|
||||
|
||||
```
|
||||
#@ comment: mypkg blah blub
|
||||
#@ filter: mypkg != 1.0.0
|
||||
#@ ignore: mypkg, otherpkg
|
||||
#@ replace: foo bar
|
||||
```
|
||||
@@ -1,3 +0,0 @@
|
||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||
|
||||
check-manifest==0.35
|
||||
@@ -1 +0,0 @@
|
||||
check-manifest
|
||||
@@ -1,9 +0,0 @@
|
||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||
|
||||
certifi==2017.7.27.1
|
||||
chardet==3.0.4
|
||||
codecov==2.0.9
|
||||
coverage==4.4.1
|
||||
idna==2.6
|
||||
requests==2.18.4
|
||||
urllib3==1.22
|
||||
@@ -1 +0,0 @@
|
||||
codecov
|
||||
@@ -1,23 +0,0 @@
|
||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||
|
||||
flake8==2.6.2 # rq.filter: < 3.0.0
|
||||
flake8-copyright==0.2.0
|
||||
flake8-debugger==1.4.0 # rq.filter: != 2.0.0
|
||||
flake8-deprecated==1.2.1
|
||||
flake8-docstrings==1.0.3 # rq.filter: < 1.1.0
|
||||
flake8-future-import==0.4.3
|
||||
flake8-mock==0.3
|
||||
flake8-pep3101==1.0 # rq.filter: < 1.1
|
||||
flake8-polyfill==1.0.1
|
||||
flake8-putty==0.4.0
|
||||
flake8-string-format==0.2.3
|
||||
flake8-tidy-imports==1.1.0
|
||||
flake8-tuple==0.2.13
|
||||
mccabe==0.6.1
|
||||
packaging==16.8
|
||||
pep8-naming==0.4.1
|
||||
pycodestyle==2.3.1
|
||||
pydocstyle==1.1.1 # rq.filter: < 2.0.0
|
||||
pyflakes==1.6.0
|
||||
pyparsing==2.2.0
|
||||
six==1.11.0
|
||||
@@ -1,29 +0,0 @@
|
||||
flake8<3.0.0
|
||||
flake8-copyright
|
||||
flake8-debugger!=2.0.0
|
||||
flake8-deprecated
|
||||
flake8-docstrings<1.1.0
|
||||
flake8-future-import
|
||||
flake8-mock
|
||||
flake8-pep3101<1.1
|
||||
flake8-putty
|
||||
flake8-string-format
|
||||
flake8-tidy-imports
|
||||
flake8-tuple
|
||||
pep8-naming
|
||||
pydocstyle<2.0.0
|
||||
pyflakes
|
||||
|
||||
# Pinned to 2.0.0 otherwise
|
||||
pycodestyle==2.3.1
|
||||
# Pinned to 0.5.3 otherwise
|
||||
mccabe==0.6.1
|
||||
|
||||
# Waiting until flake8-putty updated
|
||||
#@ filter: flake8 < 3.0.0
|
||||
#@ filter: pydocstyle < 2.0.0
|
||||
#@ filter: flake8-docstrings < 1.1.0
|
||||
#@ filter: flake8-pep3101 < 1.1
|
||||
|
||||
# https://github.com/JBKahn/flake8-debugger/issues/5
|
||||
#@ filter: flake8-debugger != 2.0.0
|
||||
@@ -1,8 +0,0 @@
|
||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||
|
||||
appdirs==1.4.3
|
||||
packaging==16.8
|
||||
pyparsing==2.2.0
|
||||
setuptools==36.5.0
|
||||
six==1.11.0
|
||||
wheel==0.30.0
|
||||
@@ -1,7 +0,0 @@
|
||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||
|
||||
altgraph==0.14
|
||||
future==0.16.0
|
||||
macholib==1.8
|
||||
pefile==2017.9.3
|
||||
-e git+https://github.com/pyinstaller/pyinstaller.git@develop#egg=PyInstaller
|
||||
@@ -1,4 +0,0 @@
|
||||
-e git+https://github.com/pyinstaller/pyinstaller.git@develop#egg=PyInstaller
|
||||
|
||||
# remove @commit-id for scm installs
|
||||
#@ replace: @.*# @develop#
|
||||
@@ -1,18 +0,0 @@
|
||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||
|
||||
-e git+https://github.com/PyCQA/astroid.git#egg=astroid
|
||||
certifi==2017.7.27.1
|
||||
chardet==3.0.4
|
||||
github3.py==0.9.6
|
||||
idna==2.6
|
||||
isort==4.2.15
|
||||
lazy-object-proxy==1.3.1
|
||||
mccabe==0.6.1
|
||||
-e git+https://github.com/PyCQA/pylint.git#egg=pylint
|
||||
./scripts/dev/pylint_checkers
|
||||
requests==2.18.4
|
||||
six==1.11.0
|
||||
uritemplate==3.0.0
|
||||
uritemplate.py==3.0.2
|
||||
urllib3==1.22
|
||||
wrapt==1.10.11
|
||||
@@ -1,11 +0,0 @@
|
||||
-e git+https://github.com/PyCQA/astroid.git#egg=astroid
|
||||
-e git+https://github.com/PyCQA/pylint.git#egg=pylint
|
||||
./scripts/dev/pylint_checkers
|
||||
requests
|
||||
github3.py
|
||||
|
||||
# remove @commit-id for scm installs
|
||||
#@ replace: @.*# #
|
||||
|
||||
# fix qute-pylint location
|
||||
#@ replace: qute-pylint==.* ./scripts/dev/pylint_checkers
|
||||
@@ -1,18 +0,0 @@
|
||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||
|
||||
astroid==1.5.3
|
||||
certifi==2017.7.27.1
|
||||
chardet==3.0.4
|
||||
github3.py==0.9.6
|
||||
idna==2.6
|
||||
isort==4.2.15
|
||||
lazy-object-proxy==1.3.1
|
||||
mccabe==0.6.1
|
||||
pylint==1.7.4
|
||||
./scripts/dev/pylint_checkers
|
||||
requests==2.18.4
|
||||
six==1.11.0
|
||||
uritemplate==3.0.0
|
||||
uritemplate.py==3.0.2
|
||||
urllib3==1.22
|
||||
wrapt==1.10.11
|
||||
@@ -1,7 +0,0 @@
|
||||
pylint
|
||||
./scripts/dev/pylint_checkers
|
||||
requests
|
||||
github3.py
|
||||
|
||||
# fix qute-pylint location
|
||||
#@ replace: qute-pylint==.* ./scripts/dev/pylint_checkers
|
||||
@@ -1,4 +0,0 @@
|
||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||
|
||||
PyQt5==5.9.1
|
||||
sip==4.19.4
|
||||
@@ -1 +0,0 @@
|
||||
PyQt5
|
||||
@@ -1,4 +0,0 @@
|
||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||
|
||||
docutils==0.14
|
||||
pyroma==2.2
|
||||
@@ -1 +0,0 @@
|
||||
pyroma
|
||||
@@ -1,7 +0,0 @@
|
||||
Jinja2
|
||||
Pygments
|
||||
pyPEG2
|
||||
PyYAML
|
||||
colorama
|
||||
cssutils
|
||||
attrs
|
||||
@@ -1,48 +0,0 @@
|
||||
bzr+lp:beautifulsoup
|
||||
git+https://github.com/cherrypy/cheroot.git
|
||||
hg+https://bitbucket.org/ned/coveragepy
|
||||
git+https://github.com/micheles/decorator.git
|
||||
git+https://github.com/pallets/flask.git
|
||||
git+https://github.com/miracle2k/python-glob2.git
|
||||
git+https://github.com/HypothesisWorks/hypothesis-python.git
|
||||
git+https://github.com/pallets/itsdangerous.git
|
||||
git+https://bitbucket.org/zzzeek/mako.git
|
||||
git+https://github.com/r1chardj0n3s/parse.git
|
||||
git+https://github.com/jenisys/parse_type.git
|
||||
hg+https://bitbucket.org/pytest-dev/py
|
||||
git+https://github.com/pytest-dev/pytest.git@features
|
||||
git+https://github.com/pytest-dev/pytest-bdd.git
|
||||
|
||||
# This is broken at the moment because logfail tries to access
|
||||
# LogCaptureHandler
|
||||
# git+https://github.com/eisensheng/pytest-catchlog.git
|
||||
pytest-catchlog==1.2.2
|
||||
|
||||
git+https://github.com/pytest-dev/pytest-cov.git
|
||||
git+https://github.com/pytest-dev/pytest-faulthandler.git
|
||||
git+https://github.com/pytest-dev/pytest-instafail.git
|
||||
git+https://github.com/pytest-dev/pytest-mock.git
|
||||
git+https://github.com/pytest-dev/pytest-qt.git
|
||||
git+https://github.com/pytest-dev/pytest-repeat.git
|
||||
git+https://github.com/pytest-dev/pytest-rerunfailures.git
|
||||
git+https://github.com/abusalimov/pytest-travis-fold.git
|
||||
git+https://github.com/The-Compiler/pytest-xvfb.git
|
||||
hg+https://bitbucket.org/gutworth/six
|
||||
hg+https://bitbucket.org/jendrikseipp/vulture
|
||||
git+https://github.com/pallets/werkzeug.git
|
||||
|
||||
|
||||
## qutebrowser dependencies
|
||||
|
||||
git+https://github.com/tartley/colorama.git
|
||||
hg+https://bitbucket.org/cthedot/cssutils
|
||||
git+https://github.com/pallets/jinja.git
|
||||
git+https://github.com/pallets/markupsafe.git
|
||||
hg+http://bitbucket.org/birkenfeld/pygments-main
|
||||
hg+https://bitbucket.org/fdik/pypeg
|
||||
git+https://github.com/python-attrs/attrs.git
|
||||
|
||||
# Fails to build:
|
||||
# gcc: error: ext/_yaml.c: No such file or directory
|
||||
# hg+https://bitbucket.org/xi/pyyaml
|
||||
PyYAML==3.12
|
||||
@@ -1,39 +0,0 @@
|
||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||
|
||||
attrs==17.2.0
|
||||
beautifulsoup4==4.6.0
|
||||
cheroot==5.8.3
|
||||
click==6.7
|
||||
# colorama==0.3.9
|
||||
coverage==4.4.1
|
||||
EasyProcess==0.2.3
|
||||
fields==5.0.0
|
||||
Flask==0.12.2
|
||||
glob2==0.6
|
||||
hunter==2.0.1
|
||||
hypothesis==3.32.0
|
||||
itsdangerous==0.24
|
||||
# Jinja2==2.9.6
|
||||
Mako==1.0.7
|
||||
# MarkupSafe==1.0
|
||||
parse==1.8.2
|
||||
parse-type==0.4.2
|
||||
py==1.4.34
|
||||
py-cpuinfo==3.3.0
|
||||
pytest==3.2.3
|
||||
pytest-bdd==2.18.2
|
||||
pytest-benchmark==3.1.1
|
||||
pytest-catchlog==1.2.2
|
||||
pytest-cov==2.5.1
|
||||
pytest-faulthandler==1.3.1
|
||||
pytest-instafail==0.3.0
|
||||
pytest-mock==1.6.3
|
||||
pytest-qt==2.2.1
|
||||
pytest-repeat==0.4.1
|
||||
pytest-rerunfailures==3.1
|
||||
pytest-travis-fold==1.2.0
|
||||
pytest-xvfb==1.0.0
|
||||
PyVirtualDisplay==0.2.1
|
||||
six==1.11.0
|
||||
vulture==0.26
|
||||
Werkzeug==0.12.2
|
||||
@@ -1,22 +0,0 @@
|
||||
beautifulsoup4
|
||||
cheroot
|
||||
coverage
|
||||
Flask
|
||||
hunter
|
||||
hypothesis
|
||||
pytest
|
||||
pytest-bdd
|
||||
pytest-benchmark
|
||||
pytest-catchlog
|
||||
pytest-cov
|
||||
pytest-faulthandler
|
||||
pytest-instafail
|
||||
pytest-mock
|
||||
pytest-qt
|
||||
pytest-repeat
|
||||
pytest-rerunfailures
|
||||
pytest-travis-fold
|
||||
pytest-xvfb
|
||||
vulture
|
||||
|
||||
#@ ignore: Jinja2, MarkupSafe, colorama
|
||||
@@ -1,6 +0,0 @@
|
||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||
|
||||
pluggy==0.5.2
|
||||
py==1.4.34
|
||||
tox==2.9.1
|
||||
virtualenv==15.1.0
|
||||
@@ -1,4 +0,0 @@
|
||||
tox
|
||||
|
||||
# The latest tox release still depends on pluggy < 0.4...
|
||||
pluggy==0.4.0
|
||||
@@ -1,3 +0,0 @@
|
||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||
|
||||
vulture==0.26
|
||||
@@ -1 +0,0 @@
|
||||
vulture
|
||||
@@ -1,150 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Behaviour
|
||||
# Userscript for qutebrowser which casts the url passed in $1 to the default
|
||||
# ChromeCast device in the network using the program `castnow`
|
||||
#
|
||||
# Usage
|
||||
# You can launch the script from qutebrowser as follows:
|
||||
# spawn --userscript ${PATH_TO_FILE} {url}
|
||||
#
|
||||
# Then, you can control the chromecast by launching the simple command
|
||||
# `castnow` in a shell which will connect to the running castnow instance.
|
||||
#
|
||||
# For stopping the script, issue the command `pkill -f castnow` which would
|
||||
# then let the rest of the userscript execute for cleaning temporary file.
|
||||
#
|
||||
# Thanks
|
||||
# This userscript borrows Thorsten Wißmann's javascript code from his `mpv`
|
||||
# userscript.
|
||||
#
|
||||
# Dependencies
|
||||
# - castnow, https://github.com/xat/castnow
|
||||
#
|
||||
# Author
|
||||
# Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
|
||||
if [ -z "$QUTE_FIFO" ] ; then
|
||||
cat 1>&2 <<EOF
|
||||
Error: $0 can not be run as a standalone script.
|
||||
|
||||
It is a qutebrowser userscript. In order to use it, call it using
|
||||
'spawn --userscript' as described in qute://help/userscripts.html
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
msg() {
|
||||
local cmd="$1"
|
||||
shift
|
||||
local msg="$*"
|
||||
if [ -z "$QUTE_FIFO" ] ; then
|
||||
echo "$cmd: $msg" >&2
|
||||
else
|
||||
echo "message-$cmd '${msg//\'/\\\'}'" >> "$QUTE_FIFO"
|
||||
fi
|
||||
}
|
||||
|
||||
js() {
|
||||
cat <<EOF
|
||||
|
||||
function descendantOfTagName(child, ancestorTagName) {
|
||||
// tells whether child has some (proper) ancestor
|
||||
// with the tag name ancestorTagName
|
||||
while (child.parentNode != null) {
|
||||
child = child.parentNode;
|
||||
if (typeof child.tagName === 'undefined') break;
|
||||
if (child.tagName.toUpperCase() == ancestorTagName.toUpperCase()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var App = {};
|
||||
|
||||
var all_videos = [];
|
||||
all_videos.push.apply(all_videos, document.getElementsByTagName("video"));
|
||||
all_videos.push.apply(all_videos, document.getElementsByTagName("object"));
|
||||
all_videos.push.apply(all_videos, document.getElementsByTagName("embed"));
|
||||
App.backup_videos = Array();
|
||||
App.all_replacements = Array();
|
||||
for (i = 0; i < all_videos.length; i++) {
|
||||
var video = all_videos[i];
|
||||
if (descendantOfTagName(video, "object")) {
|
||||
// skip tags that are contained in an object, because we hide
|
||||
// the object anyway.
|
||||
continue;
|
||||
}
|
||||
var replacement = document.createElement("div");
|
||||
replacement.innerHTML = "
|
||||
<p style=\\"margin-bottom: 0.5em\\">
|
||||
The video is being cast on your ChromeCast device.
|
||||
</p>
|
||||
<p>
|
||||
In order to restore this particular video
|
||||
<a style=\\"font-weight: bold;
|
||||
color: white;
|
||||
background: transparent;
|
||||
\\"
|
||||
onClick=\\"restore_video(this, " + i + ");\\"
|
||||
href=\\"javascript: restore_video(this, " + i + ")\\"
|
||||
>click here</a>.
|
||||
</p>
|
||||
";
|
||||
replacement.style.position = "relative";
|
||||
replacement.style.zIndex = "100003000000";
|
||||
replacement.style.fontSize = "1rem";
|
||||
replacement.style.textAlign = "center";
|
||||
replacement.style.verticalAlign = "middle";
|
||||
replacement.style.height = "100%";
|
||||
replacement.style.background = "#101010";
|
||||
replacement.style.color = "white";
|
||||
replacement.style.border = "4px dashed #545454";
|
||||
replacement.style.padding = "2em";
|
||||
replacement.style.margin = "auto";
|
||||
App.all_replacements[i] = replacement;
|
||||
App.backup_videos[i] = video;
|
||||
video.parentNode.replaceChild(replacement, video);
|
||||
}
|
||||
|
||||
function restore_video(obj, index) {
|
||||
obj = App.all_replacements[index];
|
||||
video = App.backup_videos[index];
|
||||
console.log(video);
|
||||
obj.parentNode.replaceChild(video, obj);
|
||||
}
|
||||
|
||||
/** force repainting the video, thanks to:
|
||||
* http://martinwolf.org/2014/06/10/force-repaint-of-an-element-with-javascript/
|
||||
*/
|
||||
var siteHeader = document.getElementById('header');
|
||||
siteHeader.style.display='none';
|
||||
siteHeader.offsetHeight; // no need to store this anywhere, the reference is enough
|
||||
siteHeader.style.display='block';
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
printjs() {
|
||||
js | sed 's,//.*$,,' | tr '\n' ' '
|
||||
}
|
||||
echo "jseval -q $(printjs)" >> "$QUTE_FIFO"
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
file_to_cast=${tmpdir}/qutecast
|
||||
|
||||
# kill any running instance of castnow
|
||||
pkill -f /usr/bin/castnow
|
||||
|
||||
# start youtube download in stream mode (-o -) into temporary file
|
||||
youtube-dl -qo - "$1" > ${file_to_cast} &
|
||||
ytdl_pid=$!
|
||||
|
||||
msg info "Casting $1" >> "$QUTE_FIFO"
|
||||
# start castnow in stream mode to cast on ChromeCast
|
||||
tail -F "${file_to_cast}" | castnow -
|
||||
|
||||
# cleanup remaining background process and file on disk
|
||||
kill ${ytdl_pid}
|
||||
rm -rf ${tmpdir}
|
||||
@@ -1,48 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2015 Zach-Button <zachrey.button@gmail.com>
|
||||
# Copyright 2015-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
||||
#
|
||||
# This file is part of qutebrowser.
|
||||
#
|
||||
# qutebrowser is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# qutebrowser is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Pipes history, quickmarks, and URL into dmenu.
|
||||
#
|
||||
# If run from qutebrowser as a userscript, it runs :open on the URL
|
||||
# If not, it opens a new qutebrowser window at the URL
|
||||
#
|
||||
# Ideal for use with tabs_are_windows. Set a hotkey to launch this script, then:
|
||||
# :bind o spawn --userscript dmenu_qutebrowser
|
||||
#
|
||||
# Use the hotkey to open in new tab/window, press 'o' to open URL in current tab/window
|
||||
# You can simulate "go" by pressing "o<tab>", as the current URL is always first in the list
|
||||
#
|
||||
# I personally use "<Mod4>o" to launch this script. For me, my workflow is:
|
||||
# Default keys Keys with this script
|
||||
# O <Mod4>o
|
||||
# o o
|
||||
# go o<Tab>
|
||||
# gO gC, then o<Tab>
|
||||
# (This is unnecessarily long. I use this rarely, feel free to make this script accept parameters.)
|
||||
#
|
||||
|
||||
[ -z "$QUTE_URL" ] && QUTE_URL='http://google.com'
|
||||
|
||||
url=$(echo "$QUTE_URL" | cat - "$QUTE_CONFIG_DIR/quickmarks" "$QUTE_DATA_DIR/history" | dmenu -l 15 -p qutebrowser)
|
||||
url=$(echo "$url" | sed -E 's/[^ ]+ +//g' | egrep "https?:" || echo "$url")
|
||||
|
||||
[ -z "${url// }" ] && exit
|
||||
|
||||
echo "open $url" >> "$QUTE_FIFO" || qutebrowser "$url"
|
||||
@@ -1,47 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Behavior:
|
||||
# Userscript for qutebrowser which will take the raw JSON text of the current
|
||||
# page, format it using `jq`, will add syntax highlighting using `pygments`,
|
||||
# and open the syntax highlighted pretty printed html in a new tab. If the file
|
||||
# is larger than 10MB then this script will only indent the json and will forego
|
||||
# syntax highlighting using pygments.
|
||||
#
|
||||
# In order to use this script, just start it using `spawn --userscript` from
|
||||
# qutebrowser. I recommend using an alias, e.g. put this in the
|
||||
# [alias]-section of qutebrowser.conf:
|
||||
#
|
||||
# json = spawn --userscript /path/to/json_format
|
||||
#
|
||||
# Note that the color style defaults to monokai, but a different pygments style
|
||||
# can be passed as the first parameter to the script. A full list of the pygments
|
||||
# styles can be found at: https://help.farbox.com/pygments.html
|
||||
#
|
||||
# Bryan Gilbert, 2017
|
||||
|
||||
# default style to monokai if none is provided
|
||||
STYLE=${1:-monokai}
|
||||
# format json using jq
|
||||
FORMATTED_JSON="$(cat "$QUTE_TEXT" | jq '.')"
|
||||
|
||||
# if jq command failed or formatted json is empty, assume failure and terminate
|
||||
if [ $? -ne 0 ] || [ -z "$FORMATTED_JSON" ]; then
|
||||
echo "Invalid json, aborting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# calculate the filesize of the json document
|
||||
FILE_SIZE=$(ls -s --block-size=1048576 "$QUTE_TEXT" | cut -d' ' -f1)
|
||||
|
||||
# use pygments to pretty-up the json (syntax highlight) if file is less than 10MB
|
||||
if [ "$FILE_SIZE" -lt "10" ]; then
|
||||
FORMATTED_JSON="$(echo "$FORMATTED_JSON" | pygmentize -l json -f html -O full,style=$STYLE)"
|
||||
fi
|
||||
|
||||
# create a temp file and write the formatted json to that file
|
||||
TEMP_FILE="$(mktemp --suffix '.html')"
|
||||
echo "$FORMATTED_JSON" > $TEMP_FILE
|
||||
|
||||
|
||||
# send the command to qutebrowser to open the new file containing the formatted json
|
||||
echo "open -t file://$TEMP_FILE" >> "$QUTE_FIFO"
|
||||
@@ -1,114 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Both standalone script and qutebrowser userscript that opens a rofi menu with
|
||||
# all files from the download director and opens the selected file. It works
|
||||
# both as a userscript and a standalone script that is called from outside of
|
||||
# qutebrowser.
|
||||
#
|
||||
# Suggested keybinding (for "show downloads"):
|
||||
# spawn --userscript ~/.config/qutebrowser/open_download
|
||||
# sd
|
||||
#
|
||||
# Requirements:
|
||||
# - rofi (in a recent version)
|
||||
# - xdg-open and xdg-mime
|
||||
# - You should configure qutebrowser to download files to a single directory
|
||||
# - It comes in handy if you enable downloads.remove_finished. If you want to
|
||||
# see the recent downloads, just press "sd".
|
||||
#
|
||||
# Thorsten Wißmann, 2015 (thorsten` on freenode)
|
||||
# Any feedback is welcome!
|
||||
|
||||
set -e
|
||||
|
||||
# open a file from the download directory using rofi
|
||||
DOWNLOAD_DIR=${DOWNLOAD_DIR:-$QUTE_DOWNLOAD_DIR}
|
||||
DOWNLOAD_DIR=${DOWNLOAD_DIR:-$HOME/Downloads}
|
||||
# the name of the rofi command
|
||||
ROFI_CMD=${ROFI_CMD:-rofi}
|
||||
ROFI_ARGS=${ROFI_ARGS:-}
|
||||
|
||||
msg() {
|
||||
local cmd="$1"
|
||||
shift
|
||||
local msg="$*"
|
||||
if [ -z "$QUTE_FIFO" ] ; then
|
||||
echo "$cmd: $msg" >&2
|
||||
else
|
||||
echo "message-$cmd '${msg//\'/\\\'}'" >> "$QUTE_FIFO"
|
||||
fi
|
||||
}
|
||||
die() {
|
||||
msg error "$*"
|
||||
if [ -n "$QUTE_FIFO" ] ; then
|
||||
# when run as a userscript, the above error message already informs the
|
||||
# user about the failure, and no additional "userscript exited with status
|
||||
# 1" is needed.
|
||||
exit 0;
|
||||
else
|
||||
exit 1;
|
||||
fi
|
||||
}
|
||||
|
||||
if ! [ -d "$DOWNLOAD_DIR" ] ; then
|
||||
die "Download directory »$DOWNLOAD_DIR« not found!"
|
||||
fi
|
||||
if ! which "${ROFI_CMD}" > /dev/null ; then
|
||||
die "Rofi command »${ROFI_CMD}« not found in PATH!"
|
||||
fi
|
||||
|
||||
rofi_default_args=(
|
||||
-monitor -2 # place above window
|
||||
-location 6 # aligned at the bottom
|
||||
-width 100 # use full window width
|
||||
-i
|
||||
-no-custom
|
||||
-format i # make rofi return the index
|
||||
-l 10
|
||||
-p 'Open download:' -dmenu
|
||||
)
|
||||
|
||||
crop-first-column() {
|
||||
local maxlength=${1:-40}
|
||||
local expression='s|^\([^\t]\{0,'"$maxlength"'\}\)[^\t]*\t|\1\t|'
|
||||
sed "$expression"
|
||||
}
|
||||
|
||||
ls-files() {
|
||||
# add the slash at the end of the download dir enforces to follow the
|
||||
# symlink, if the DOWNLOAD_DIR itself is a symlink
|
||||
ls -Q --quoting-style escape -h -o -1 -A -t "${DOWNLOAD_DIR}/" \
|
||||
| grep '^[-]' \
|
||||
| cut -d' ' -f3- \
|
||||
| sed 's,^\(.*[^\]\) \(.*\)$,\2\t\1,' \
|
||||
| sed 's,\\\(.\),\1,g'
|
||||
}
|
||||
|
||||
mapfile -t entries < <(ls-files)
|
||||
|
||||
# we need to manually check that there are items, because rofi doesn't show up
|
||||
# if there are no items and -no-custom is passed to rofi.
|
||||
if [ "${#entries[@]}" -eq 0 ] ; then
|
||||
die "Download directory »${DOWNLOAD_DIR}« empty"
|
||||
fi
|
||||
|
||||
line=$(printf "%s\n" "${entries[@]}" \
|
||||
| crop-first-column 55 \
|
||||
| column -s $'\t' -t \
|
||||
| $ROFI_CMD "${rofi_default_args[@]}" $ROFI_ARGS) || true
|
||||
if [ -z "$line" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
file="${entries[$line]}"
|
||||
file="${file%%$'\t'*}"
|
||||
path="$DOWNLOAD_DIR/$file"
|
||||
filetype=$(xdg-mime query filetype "$path")
|
||||
application=$(xdg-mime query default "$filetype")
|
||||
|
||||
if [ -z "$application" ] ; then
|
||||
die "Do not know how to open »$file« of type $filetype"
|
||||
fi
|
||||
|
||||
msg info "Opening »$file« (of type $filetype) with ${application%.desktop}"
|
||||
|
||||
xdg-open "$path" &
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2015 jnphilipp <me@jnphilipp.org>
|
||||
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
||||
#
|
||||
# This file is part of qutebrowser.
|
||||
#
|
||||
# qutebrowser is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# qutebrowser is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Opens all links to feeds defined in the head of a site
|
||||
#
|
||||
# Ideal for use with tabs_are_windows. Set a hotkey to launch this script, then:
|
||||
# :bind gF spawn --userscript openfeeds
|
||||
#
|
||||
# Use the hotkey to open the feeds in new tab/window, press 'gF' to open
|
||||
#
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
from urllib.parse import urljoin
|
||||
|
||||
with open(os.environ['QUTE_HTML'], 'r') as f:
|
||||
soup = BeautifulSoup(f)
|
||||
with open(os.environ['QUTE_FIFO'], 'w') as f:
|
||||
for link in soup.find_all('link', rel='alternate', type=re.compile(r'application/((rss|rdf|atom)\+)?xml|text/xml')):
|
||||
f.write('open -t %s\n' % urljoin(os.environ['QUTE_URL'], link.get('href')))
|
||||
@@ -1,380 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
help() {
|
||||
blink=$'\e[1;31m' reset=$'\e[0m'
|
||||
cat <<EOF
|
||||
This script can only be used as a userscript for qutebrowser
|
||||
2015, Thorsten Wißmann <edu _at_ thorsten-wissmann _dot_ de>
|
||||
In case of questions or suggestions, do not hesitate to send me an E-Mail or to
|
||||
directly ask me via IRC (nickname thorsten\`) in #qutebrowser on freenode.
|
||||
|
||||
$blink!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$reset
|
||||
WARNING: the passwords are stored in qutebrowser's
|
||||
debug log reachable via the url qute://log
|
||||
$blink!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$reset
|
||||
|
||||
Usage: run as a userscript form qutebrowser, e.g.:
|
||||
spawn --userscript ~/.config/qutebrowser/password_fill
|
||||
|
||||
Pass backend: (see also passwordstore.org)
|
||||
This script expects pass to store the credentials of each page in an extra
|
||||
file, where the filename (or filepath) contains the domain of the respective
|
||||
page. The first line of the file must contain the password, the login name
|
||||
must be contained in a later line beginning with "user:", "login:", or
|
||||
"username:" (configurable by the user_pattern variable).
|
||||
|
||||
Behavior:
|
||||
It will try to find a username/password entry in the configured backend
|
||||
(currently only pass) for the current website and will load that pair of
|
||||
username and password to any form on the current page that has some password
|
||||
entry field. If multiple entries are found, a zenity menu is offered.
|
||||
|
||||
If no entry is found, then it crops subdomains from the url if at least one
|
||||
entry is found in the backend. (In that case, it always shows a menu)
|
||||
|
||||
Configuration:
|
||||
This script loads the bash script ~/.config/qutebrowser/password_fill_rc (if
|
||||
it exists), so you can change any configuration variable and overwrite any
|
||||
function you like.
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
shopt -s nocasematch # make regexp matching in bash case insensitive
|
||||
|
||||
if [ -z "$QUTE_FIFO" ] ; then
|
||||
help
|
||||
exit
|
||||
fi
|
||||
|
||||
error() {
|
||||
local msg="$*"
|
||||
echo "message-error '${msg//\'/\\\'}'" >> "$QUTE_FIFO"
|
||||
}
|
||||
msg() {
|
||||
local msg="$*"
|
||||
echo "message-info '${msg//\'/\\\'}'" >> "$QUTE_FIFO"
|
||||
}
|
||||
die() {
|
||||
error "$*"
|
||||
exit 0
|
||||
}
|
||||
|
||||
javascript_escape() {
|
||||
# print the first argument in an escaped way, such that it can safely
|
||||
# be used within javascripts double quotes
|
||||
sed "s,[\\\'\"],\\\&,g" <<< "$1"
|
||||
}
|
||||
|
||||
# ======================================================= #
|
||||
# CONFIGURATION
|
||||
# ======================================================= #
|
||||
# The configuration file is per default located in
|
||||
# ~/.config/qutebrowser/password_fill_rc and is a bash script that is loaded
|
||||
# later in the present script. So basically you can replace all of the
|
||||
# following definitions and make them fit your needs.
|
||||
|
||||
# The following simplifies a URL to the domain (e.g. "wiki.qutebrowser.org")
|
||||
# which is later used to search the correct entries in the password backend. If
|
||||
# you e.g. don't want the "www." to be removed or if you want to distinguish
|
||||
# between different paths on the same domain.
|
||||
|
||||
simplify_url() {
|
||||
simple_url="${1##*://}" # remove protocol specification
|
||||
simple_url="${simple_url%%\?*}" # remove GET parameters
|
||||
simple_url="${simple_url%%/*}" # remove directory path
|
||||
simple_url="${simple_url%:*}" # remove port
|
||||
simple_url="${simple_url##www.}" # remove www. subdomain
|
||||
}
|
||||
|
||||
# no_entries_found() is called if the first query_entries() call did not find
|
||||
# any matching entries. Multiple implementations are possible:
|
||||
# The easiest behavior is to quit:
|
||||
#no_entries_found() {
|
||||
# if [ 0 -eq "${#files[@]}" ] ; then
|
||||
# die "No entry found for »$simple_url«"
|
||||
# fi
|
||||
#}
|
||||
# But you could also fill the files array with all entries from your pass db
|
||||
# if the first db query did not find anything
|
||||
# no_entries_found() {
|
||||
# if [ 0 -eq "${#files[@]}" ] ; then
|
||||
# query_entries ""
|
||||
# if [ 0 -eq "${#files[@]}" ] ; then
|
||||
# die "No entry found for »$simple_url«"
|
||||
# fi
|
||||
# fi
|
||||
# }
|
||||
|
||||
# Another behavior is to drop another level of subdomains until search hits
|
||||
# are found:
|
||||
no_entries_found() {
|
||||
while [ 0 -eq "${#files[@]}" ] && [ -n "$simple_url" ]; do
|
||||
shorter_simple_url=$(sed 's,^[^.]*\.,,' <<< "$simple_url")
|
||||
if [ "$shorter_simple_url" = "$simple_url" ] ; then
|
||||
# if no dot, then even remove the top level domain
|
||||
simple_url=""
|
||||
query_entries "$simple_url"
|
||||
break
|
||||
fi
|
||||
simple_url="$shorter_simple_url"
|
||||
query_entries "$simple_url"
|
||||
#die "No entry found for »$simple_url«"
|
||||
# enforce menu if we do "fuzzy" matching
|
||||
menu_if_one_entry=1
|
||||
done
|
||||
if [ 0 -eq "${#files[@]}" ] ; then
|
||||
die "No entry found for »$simple_url«"
|
||||
fi
|
||||
}
|
||||
|
||||
# Backend implementations tell, how the actual password store is accessed.
|
||||
# Right now, there is only one fully functional password backend, namely for
|
||||
# the program "pass".
|
||||
# A password backend consists of three actions:
|
||||
# - init() initializes backend-specific things and does sanity checks.
|
||||
# - query_entries() is called with a simplified url and is expected to fill
|
||||
# the bash array $files with the names of matching password entries. There
|
||||
# are no requirements how these names should look like.
|
||||
# - open_entry() is called with some specific entry of the $files array and is
|
||||
# expected to write the username of that entry to the $username variable and
|
||||
# the corresponding password to $password
|
||||
|
||||
reset_backend() {
|
||||
init() { true ; }
|
||||
query_entries() { true ; }
|
||||
open_entry() { true ; }
|
||||
}
|
||||
|
||||
# choose_entry() is expected to choose one entry from the array $files and
|
||||
# write it to the variable $file.
|
||||
choose_entry() {
|
||||
choose_entry_zenity
|
||||
}
|
||||
|
||||
# The default implementation chooses a random entry from the array. So if there
|
||||
# are multiple matching entries, multiple calls to this userscript will
|
||||
# eventually pick the "correct" entry. I.e. if this userscript is bound to
|
||||
# "zl", the user has to press "zl" until the correct username shows up in the
|
||||
# login form.
|
||||
choose_entry_random() {
|
||||
local nr=${#files[@]}
|
||||
file="${files[$((RANDOM % nr))]}"
|
||||
# Warn user, that there might be other matching password entries
|
||||
if [ "$nr" -gt 1 ] ; then
|
||||
msg "Picked $file out of $nr entries: ${files[*]}"
|
||||
fi
|
||||
}
|
||||
|
||||
# another implementation would be to ask the user via some menu (like rofi or
|
||||
# dmenu or zenity or even qutebrowser completion in future?) which entry to
|
||||
# pick
|
||||
MENU_COMMAND=( head -n 1 )
|
||||
# whether to show the menu if there is only one entry in it
|
||||
menu_if_one_entry=0
|
||||
choose_entry_menu() {
|
||||
local nr=${#files[@]}
|
||||
if [ "$nr" -eq 1 ] && ! ((menu_if_one_entry)) ; then
|
||||
file="${files[0]}"
|
||||
else
|
||||
file=$( printf "%s\n" "${files[@]}" | "${MENU_COMMAND[@]}" )
|
||||
fi
|
||||
}
|
||||
|
||||
choose_entry_rofi() {
|
||||
MENU_COMMAND=( rofi -p "qutebrowser> " -dmenu
|
||||
-mesg $'Pick a password entry for <b>'"${QUTE_URL//&/&}"'</b>' )
|
||||
choose_entry_menu || true
|
||||
}
|
||||
|
||||
choose_entry_zenity() {
|
||||
MENU_COMMAND=( zenity --list --title "qutebrowser password fill"
|
||||
--text "Pick the password entry:"
|
||||
--column "Name" )
|
||||
choose_entry_menu || true
|
||||
}
|
||||
|
||||
choose_entry_zenity_radio() {
|
||||
zenity_helper() {
|
||||
awk '{ print $0 ; print $0 }' \
|
||||
| zenity --list --radiolist \
|
||||
--title "qutebrowser password fill" \
|
||||
--text "Pick the password entry:" \
|
||||
--column " " --column "Name"
|
||||
}
|
||||
MENU_COMMAND=( zenity_helper )
|
||||
choose_entry_menu || true
|
||||
}
|
||||
|
||||
# =======================================================
|
||||
# backend: PASS
|
||||
|
||||
# configuration options:
|
||||
match_filename=1 # whether allowing entry match by filepath
|
||||
match_line=0 # whether allowing entry match by URL-Pattern in file
|
||||
# Note: match_line=1 gets very slow, even for small password stores!
|
||||
match_line_pattern='^url: .*' # applied using grep -iE
|
||||
user_pattern='^(user|username|login): '
|
||||
|
||||
GPG_OPTS=( "--quiet" "--yes" "--compress-algo=none" "--no-encrypt-to" )
|
||||
GPG="gpg"
|
||||
export GPG_TTY="${GPG_TTY:-$(tty 2>/dev/null)}"
|
||||
which gpg2 &>/dev/null && GPG="gpg2"
|
||||
[[ -n $GPG_AGENT_INFO || $GPG == "gpg2" ]] && GPG_OPTS+=( "--batch" "--use-agent" )
|
||||
|
||||
pass_backend() {
|
||||
init() {
|
||||
PREFIX="${PASSWORD_STORE_DIR:-$HOME/.password-store}"
|
||||
if ! [ -d "$PREFIX" ] ; then
|
||||
die "Can not open password store dir »$PREFIX«"
|
||||
fi
|
||||
}
|
||||
query_entries() {
|
||||
local url="$1"
|
||||
|
||||
if ((match_line)) ; then
|
||||
# add entries with matching URL-tag
|
||||
while read -r -d "" passfile ; do
|
||||
if $GPG "${GPG_OPTS}" -d "$passfile" \
|
||||
| grep --max-count=1 -iE "${match_line_pattern}${url}" > /dev/null
|
||||
then
|
||||
passfile="${passfile#$PREFIX}"
|
||||
passfile="${passfile#/}"
|
||||
files+=( "${passfile%.gpg}" )
|
||||
fi
|
||||
done < <(find -L "$PREFIX" -iname '*.gpg' -print0)
|
||||
fi
|
||||
if ((match_filename)) ; then
|
||||
# add entries with matching filepath
|
||||
while read -r passfile ; do
|
||||
passfile="${passfile#$PREFIX}"
|
||||
passfile="${passfile#/}"
|
||||
files+=( "${passfile%.gpg}" )
|
||||
done < <(find -L "$PREFIX" -iname '*.gpg' | grep "$url")
|
||||
fi
|
||||
}
|
||||
open_entry() {
|
||||
local path="$PREFIX/${1}.gpg"
|
||||
password=""
|
||||
local firstline=1
|
||||
while read -r line ; do
|
||||
if ((firstline)) ; then
|
||||
password="$line"
|
||||
firstline=0
|
||||
else
|
||||
if [[ $line =~ $user_pattern ]] ; then
|
||||
# remove the matching prefix "user: " from the beginning of the line
|
||||
username=${line#${BASH_REMATCH[0]}}
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done < <($GPG "${GPG_OPTS}" -d "$path" )
|
||||
}
|
||||
}
|
||||
# =======================================================
|
||||
|
||||
# =======================================================
|
||||
# backend: secret
|
||||
secret_backend() {
|
||||
init() {
|
||||
return
|
||||
}
|
||||
query_entries() {
|
||||
local domain="$1"
|
||||
while read -r line ; do
|
||||
if [[ "$line" =~ "attribute.username = " ]] ; then
|
||||
files+=("$domain ${line#${BASH_REMATCH[0]}}")
|
||||
fi
|
||||
done < <( secret-tool search --unlock --all domain "$domain" 2>&1 )
|
||||
}
|
||||
open_entry() {
|
||||
local domain="${1%% *}"
|
||||
username="${1#* }"
|
||||
password=$(secret-tool lookup domain "$domain" username "$username")
|
||||
}
|
||||
}
|
||||
# =======================================================
|
||||
|
||||
# load some sane default backend
|
||||
reset_backend
|
||||
pass_backend
|
||||
# load configuration
|
||||
QUTE_CONFIG_DIR=${QUTE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/qutebrowser/}
|
||||
PWFILL_CONFIG=${PWFILL_CONFIG:-${QUTE_CONFIG_DIR}/password_fill_rc}
|
||||
if [ -f "$PWFILL_CONFIG" ] ; then
|
||||
source "$PWFILL_CONFIG"
|
||||
fi
|
||||
init
|
||||
|
||||
simplify_url "$QUTE_URL"
|
||||
query_entries "${simple_url}"
|
||||
no_entries_found
|
||||
# remove duplicates
|
||||
mapfile -t files < <(printf "%s\n" "${files[@]}" | sort | uniq )
|
||||
choose_entry
|
||||
if [ -z "$file" ] ; then
|
||||
# choose_entry didn't want any of these entries
|
||||
exit 0
|
||||
fi
|
||||
open_entry "$file"
|
||||
#username="$(date)"
|
||||
#password="XYZ"
|
||||
#msg "$username, ${#password}"
|
||||
|
||||
[ -n "$username" ] || die "Username not set in entry $file"
|
||||
[ -n "$password" ] || die "Password not set in entry $file"
|
||||
|
||||
js() {
|
||||
cat <<EOF
|
||||
function isVisible(elem) {
|
||||
var style = elem.ownerDocument.defaultView.getComputedStyle(elem, null);
|
||||
|
||||
if (style.getPropertyValue("visibility") !== "visible" ||
|
||||
style.getPropertyValue("display") === "none" ||
|
||||
style.getPropertyValue("opacity") === "0") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return elem.offsetWidth > 0 && elem.offsetHeight > 0;
|
||||
};
|
||||
function hasPasswordField(form) {
|
||||
var inputs = form.getElementsByTagName("input");
|
||||
for (var j = 0; j < inputs.length; j++) {
|
||||
var input = inputs[j];
|
||||
if (input.type == "password") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
function loadData2Form (form) {
|
||||
var inputs = form.getElementsByTagName("input");
|
||||
for (var j = 0; j < inputs.length; j++) {
|
||||
var input = inputs[j];
|
||||
if (isVisible(input) && (input.type == "text" || input.type == "email")) {
|
||||
input.focus();
|
||||
input.value = "$(javascript_escape "${username}")";
|
||||
input.blur();
|
||||
}
|
||||
if (input.type == "password") {
|
||||
input.focus();
|
||||
input.value = "$(javascript_escape "${password}")";
|
||||
input.blur();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var forms = document.getElementsByTagName("form");
|
||||
for (i = 0; i < forms.length; i++) {
|
||||
if (hasPasswordField(forms[i])) {
|
||||
loadData2Form(forms[i]);
|
||||
}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
printjs() {
|
||||
js | sed 's,//.*$,,' | tr '\n' ' '
|
||||
}
|
||||
echo "jseval -q $(printjs)" >> "$QUTE_FIFO"
|
||||
@@ -1,33 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2015 Zach-Button <zachrey.button@gmail.com>
|
||||
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
||||
#
|
||||
# This file is part of qutebrowser.
|
||||
#
|
||||
# qutebrowser is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# qutebrowser is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# This script fetches the unprocessed HTML source for a page and opens it in vim.
|
||||
# :bind gf spawn --userscript qutebrowser_viewsource
|
||||
#
|
||||
# Caveat: Does not use authentication of any kind. Add it in if you want it to.
|
||||
#
|
||||
|
||||
path=$(mktemp --tmpdir qutebrowser_XXXXXXXX.html)
|
||||
|
||||
curl "$QUTE_URL" > "$path"
|
||||
urxvt -e vim "$path"
|
||||
|
||||
rm "$path"
|
||||
@@ -1,59 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Handle open -s && open -t with bemenu
|
||||
|
||||
#:bind o spawn --userscript /path/to/userscripts/qutedmenu open
|
||||
#:bind O spawn --userscript /path/to/userscripts/qutedmenu tab
|
||||
|
||||
# If you would like to set a custom colorscheme/font use these dirs.
|
||||
# https://github.com/halfwit/dotfiles/blob/master/.config/dmenu/bemenucolors
|
||||
readonly confdir=${XDG_CONFIG_HOME:-$HOME/.config}
|
||||
|
||||
readonly optsfile=$confdir/dmenu/bemenucolors
|
||||
|
||||
create_menu() {
|
||||
# Check quickmarks
|
||||
while read -r url; do
|
||||
printf -- '%s\n' "$url"
|
||||
done < "$QUTE_CONFIG_DIR"/quickmarks
|
||||
|
||||
# Next bookmarks
|
||||
while read -r url _; do
|
||||
printf -- '%s\n' "$url"
|
||||
done < "$QUTE_CONFIG_DIR"/bookmarks/urls
|
||||
|
||||
# Finally history
|
||||
while read -r _ url; do
|
||||
printf -- '%s\n' "$url"
|
||||
done < "$QUTE_DATA_DIR"/history
|
||||
}
|
||||
|
||||
get_selection() {
|
||||
opts+=(-p qutebrowser)
|
||||
#create_menu | dmenu -l 10 "${opts[@]}"
|
||||
create_menu | bemenu -l 10 "${opts[@]}"
|
||||
}
|
||||
|
||||
# Main
|
||||
# https://github.com/halfwit/dotfiles/blob/master/.config/dmenu/font
|
||||
if [[ -s $confdir/dmenu/font ]]; then
|
||||
read -r font < "$confdir"/dmenu/font
|
||||
fi
|
||||
|
||||
if [[ $font ]]; then
|
||||
opts+=(-fn "$font")
|
||||
fi
|
||||
|
||||
if [[ -s $optsfile ]]; then
|
||||
source "$optsfile"
|
||||
fi
|
||||
|
||||
url=$(get_selection)
|
||||
url=${url/*http/http}
|
||||
|
||||
# If no selection is made, exit (escape pressed, e.g.)
|
||||
[[ ! $url ]] && exit 0
|
||||
|
||||
case $1 in
|
||||
open) printf '%s' "open $url" >> "$QUTE_FIFO" || qutebrowser "$url" ;;
|
||||
tab) printf '%s' "open -t $url" >> "$QUTE_FIFO" || qutebrowser "$url" ;;
|
||||
esac
|
||||
@@ -1,37 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Executes python-readability on current page and opens the summary as new tab.
|
||||
#
|
||||
# Depends on the python-readability package, or its fork:
|
||||
#
|
||||
# - https://github.com/buriy/python-readability
|
||||
# - https://github.com/bookieio/breadability
|
||||
#
|
||||
# Usage:
|
||||
# :spawn --userscript readability
|
||||
#
|
||||
from __future__ import absolute_import
|
||||
import codecs, os
|
||||
|
||||
tmpfile=os.path.expanduser('~/.local/share/qutebrowser/userscripts/readability.html')
|
||||
if not os.path.exists(os.path.dirname(tmpfile)):
|
||||
os.makedirs(os.path.dirname(tmpfile))
|
||||
|
||||
with codecs.open(os.environ['QUTE_HTML'], 'r', 'utf-8') as source:
|
||||
data = source.read()
|
||||
|
||||
try:
|
||||
from breadability.readable import Article as reader
|
||||
doc = reader(data)
|
||||
content = doc.readable
|
||||
except ImportError:
|
||||
from readability import Document
|
||||
doc = Document(data)
|
||||
content = doc.summary().replace('<html>', '<html><head><title>%s</title></head>' % doc.title())
|
||||
|
||||
with codecs.open(tmpfile, 'w', 'utf-8') as target:
|
||||
target.write('<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />')
|
||||
target.write(content)
|
||||
|
||||
with open(os.environ['QUTE_FIFO'], 'w') as fifo:
|
||||
fifo.write('open -t %s' % tmpfile)
|
||||
@@ -1,34 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Adds DuckDuckGo bang as searchengine.
|
||||
#
|
||||
# Usage:
|
||||
# :spawn --userscript ripbang [bang]...
|
||||
#
|
||||
# Example:
|
||||
# :spawn --userscript ripbang amazon maps
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
import os, re, requests, sys
|
||||
|
||||
try:
|
||||
from urllib.parse import unquote
|
||||
except ImportError:
|
||||
from urllib import unquote
|
||||
|
||||
for argument in sys.argv[1:]:
|
||||
bang = '!' + argument
|
||||
r = requests.get('https://duckduckgo.com/',
|
||||
params={'q': bang + ' SEARCHTEXT'})
|
||||
|
||||
searchengine = unquote(re.search("url=[^']+", r.text).group(0))
|
||||
searchengine = searchengine.replace('url=', '')
|
||||
searchengine = searchengine.replace('/l/?kh=-1&uddg=', '')
|
||||
searchengine = searchengine.replace('SEARCHTEXT', '{}')
|
||||
|
||||
if os.getenv('QUTE_FIFO'):
|
||||
with open(os.environ['QUTE_FIFO'], 'w') as fifo:
|
||||
fifo.write('set searchengines %s %s' % (bang, searchengine))
|
||||
else:
|
||||
print('%s %s' % (bang, searchengine))
|
||||
@@ -1,122 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright 2016 Jan Verbeek (blyxxyz) <ring@openmailbox.org>
|
||||
#
|
||||
# This file is part of qutebrowser.
|
||||
#
|
||||
# qutebrowser is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# qutebrowser is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This script keeps track of URLs in RSS feeds and opens new ones.
|
||||
# New feeds can be added with ':spawn -u /path/to/userscripts/rss add' or
|
||||
# ':spawn -u /path/to/userscripts/rss <url>'.
|
||||
# New items can be opened with ':spawn -u /path/to/userscripts/rss'.
|
||||
# The script doesn't really parse XML, and searches for things that look like
|
||||
# item links. It might open things that aren't real links, and it might miss
|
||||
# real links.
|
||||
|
||||
config_dir="$HOME/.qute-rss"
|
||||
|
||||
add_feed () {
|
||||
touch "feeds"
|
||||
if grep -Fq "$1" "feeds"; then
|
||||
notice "$1 is saved already."
|
||||
else
|
||||
printf "%s\n" "$1" >> "feeds"
|
||||
fi
|
||||
}
|
||||
|
||||
# Show an error message and exit
|
||||
fail () {
|
||||
echo "message-error '$*'" > "$QUTE_FIFO"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Get a sorted list of item URLs from a RSS feed
|
||||
get_items () {
|
||||
$curl "$@" | grep "$text_only" -zo -e '<guid[^<>]*>[^<>]*</guid>' \
|
||||
-e '<link[^<>]*>[^<>]*</link>' \
|
||||
-e '<link[^<>]*href="[^"]*"' |
|
||||
grep "$text_only" -o 'http[^<>"]*' | sort | uniq
|
||||
}
|
||||
|
||||
# Show an info message
|
||||
notice () {
|
||||
echo "message-info '$*'" > "$QUTE_FIFO"
|
||||
}
|
||||
|
||||
# Update a database of a feed and open new URLs
|
||||
read_items () {
|
||||
cd read_urls
|
||||
feed_file="$(echo "$1" | tr -d /)"
|
||||
feed_temp_file="$(mktemp "$feed_file.tmp.XXXXXXXXXX")"
|
||||
feed_new_items="$(mktemp "$feed_file.new.XXXXXXXXXX")"
|
||||
get_items "$1" > "$feed_temp_file"
|
||||
if [ ! -s "$feed_temp_file" ]; then
|
||||
notice "No items found for $1."
|
||||
rm "$feed_temp_file" "$feed_new_items"
|
||||
elif [ ! -f "$feed_file" ]; then
|
||||
notice "$1 is a new feed. All items will be marked as read."
|
||||
mv "$feed_temp_file" "$feed_file"
|
||||
rm "$feed_new_items"
|
||||
else
|
||||
sort -o "$feed_file" "$feed_file"
|
||||
comm -2 -3 "$feed_temp_file" "$feed_file" | tee "$feed_new_items"
|
||||
cat "$feed_new_items" >> "$feed_file"
|
||||
sort -o "$feed_file" "$feed_file"
|
||||
rm "$feed_temp_file" "$feed_new_items"
|
||||
fi | while read item; do
|
||||
echo "open -t $item" > "$QUTE_FIFO"
|
||||
done
|
||||
}
|
||||
|
||||
if [ ! -d "$config_dir/read_urls" ]; then
|
||||
notice "Creating configuration directory."
|
||||
mkdir -p "$config_dir/read_urls"
|
||||
fi
|
||||
|
||||
cd "$config_dir"
|
||||
|
||||
if [ $# != 0 ]; then
|
||||
for arg in "$@"; do
|
||||
if [ "$arg" = "add" ]; then
|
||||
add_feed "$QUTE_URL"
|
||||
else
|
||||
add_feed "$arg"
|
||||
fi
|
||||
done
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ ! -f "feeds" ]; then
|
||||
fail "Add feeds by running ':spawn -u rss add' or ':spawn -u rss <url>'."
|
||||
fi
|
||||
|
||||
if curl --version >&-; then
|
||||
curl="curl -sL"
|
||||
elif wget --version >&-; then
|
||||
curl="wget -qO -"
|
||||
else
|
||||
fail "Either curl or wget is needed to run this script."
|
||||
fi
|
||||
|
||||
# Detect GNU grep so we can force it to treat everything as text
|
||||
if < /dev/null grep --help 2>&1 | grep -q -- -a; then
|
||||
text_only="-a"
|
||||
fi
|
||||
|
||||
while read feed_url; do
|
||||
read_items "$feed_url" &
|
||||
done < "$config_dir/feeds"
|
||||
|
||||
wait
|
||||
@@ -1,36 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Behavior:
|
||||
# Userscript for qutebrowser which adds a task to taskwarrior.
|
||||
# If run as a command (:spawn --userscript taskadd), it creates a new task
|
||||
# with the description equal to the current page title and annotates it with
|
||||
# the current page url. Additional arguments are passed along so you can add
|
||||
# mods to the task (e.g. priority, due date, tags).
|
||||
#
|
||||
# Example:
|
||||
# :spawn --userscript taskadd due:eod pri:H
|
||||
#
|
||||
# To enable passing along extra args, I suggest using a mapping like:
|
||||
# :bind <somekey> set-cmd-text -s :spawn --userscript taskadd
|
||||
#
|
||||
# If run from hint mode, it uses the selected hint text as the description
|
||||
# and the selected hint url as the annotation.
|
||||
#
|
||||
# Ryan Roden-Corrent (rcorre), 2016
|
||||
# Any feedback is welcome!
|
||||
#
|
||||
# For more info on Taskwarrior, see http://taskwarrior.org/
|
||||
|
||||
# use either the current page title or the hint text as the task description
|
||||
[[ $QUTE_MODE == 'hints' ]] && title=$QUTE_SELECTED_TEXT || title=$QUTE_TITLE
|
||||
|
||||
# try to add the task and grab the output
|
||||
msg="$(task add $title $@ 2>&1)"
|
||||
|
||||
if [[ $? == 0 ]]; then
|
||||
# annotate the new task with the url, send the output back to the browser
|
||||
task +LATEST annotate "$QUTE_URL"
|
||||
echo "message-info '$msg'" >> $QUTE_FIFO
|
||||
else
|
||||
echo "message-error '$msg'" >> $QUTE_FIFO
|
||||
fi
|
||||
@@ -1,143 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Behavior:
|
||||
# Userscript for qutebrowser which views the current web page in mpv using
|
||||
# sensible mpv-flags. While viewing the page in MPV, all <video>, <embed>,
|
||||
# and <object> tags in the original page are temporarily removed. Clicking on
|
||||
# such a removed video restores the respective video.
|
||||
#
|
||||
# In order to use this script, just start it using `spawn --userscript` from
|
||||
# qutebrowser. I recommend using an alias, e.g. put this in the
|
||||
# [alias]-section of qutebrowser.conf:
|
||||
#
|
||||
# mpv = spawn --userscript /path/to/view_in_mpv
|
||||
#
|
||||
# Background:
|
||||
# Most of my machines are too slow to play youtube videos using html5, but
|
||||
# they work fine in mpv (and mpv has further advantages like video scaling,
|
||||
# etc). Of course, I don't want the video to be played (or even to be
|
||||
# downloaded) twice — in MPV and in qwebkit. So I often close the tab after
|
||||
# opening it in mpv. However, I actually want to keep the rest of the page
|
||||
# (comments and video suggestions), i.e. only the videos should disappear
|
||||
# when mpv is started. And that's precisely what the present script does.
|
||||
#
|
||||
# Thorsten Wißmann, 2015 (thorsten` on freenode)
|
||||
# Any feedback is welcome!
|
||||
|
||||
set -e
|
||||
|
||||
if [ -z "$QUTE_FIFO" ] ; then
|
||||
cat 1>&2 <<EOF
|
||||
Error: $0 can not be run as a standalone script.
|
||||
|
||||
It is a qutebrowser userscript. In order to use it, call it using
|
||||
'spawn --userscript' as described in qute://help/userscripts.html
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
msg() {
|
||||
local cmd="$1"
|
||||
shift
|
||||
local msg="$*"
|
||||
if [ -z "$QUTE_FIFO" ] ; then
|
||||
echo "$cmd: $msg" >&2
|
||||
else
|
||||
echo "message-$cmd '${msg//\'/\\\'}'" >> "$QUTE_FIFO"
|
||||
fi
|
||||
}
|
||||
|
||||
MPV_COMMAND=${MPV_COMMAND:-mpv}
|
||||
# Warning: spaces in single flags are not supported
|
||||
MPV_FLAGS=${MPV_FLAGS:- --force-window --no-terminal --keep-open=yes --ytdl --ytdl-raw-options=yes-playlist=}
|
||||
video_command=( "$MPV_COMMAND" $MPV_FLAGS )
|
||||
|
||||
js() {
|
||||
cat <<EOF
|
||||
|
||||
function descendantOfTagName(child, ancestorTagName) {
|
||||
// tells whether child has some (proper) ancestor
|
||||
// with the tag name ancestorTagName
|
||||
while (child.parentNode != null) {
|
||||
child = child.parentNode;
|
||||
if (typeof child.tagName === 'undefined') break;
|
||||
if (child.tagName.toUpperCase() == ancestorTagName.toUpperCase()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var App = {};
|
||||
|
||||
var all_videos = [];
|
||||
all_videos.push.apply(all_videos, document.getElementsByTagName("video"));
|
||||
all_videos.push.apply(all_videos, document.getElementsByTagName("object"));
|
||||
all_videos.push.apply(all_videos, document.getElementsByTagName("embed"));
|
||||
App.backup_videos = Array();
|
||||
App.all_replacements = Array();
|
||||
for (i = 0; i < all_videos.length; i++) {
|
||||
var video = all_videos[i];
|
||||
if (descendantOfTagName(video, "object")) {
|
||||
// skip tags that are contained in an object, because we hide
|
||||
// the object anyway.
|
||||
continue;
|
||||
}
|
||||
var replacement = document.createElement("div");
|
||||
replacement.innerHTML = "
|
||||
<p style=\\"margin-bottom: 0.5em\\">
|
||||
Opening page with:
|
||||
<span style=\\"font-family: monospace;\\">${video_command[*]}</span>
|
||||
</p>
|
||||
<p>
|
||||
In order to restore this particular video
|
||||
<a style=\\"font-weight: bold;
|
||||
color: white;
|
||||
background: transparent;
|
||||
\\"
|
||||
onClick=\\"restore_video(this, " + i + ");\\"
|
||||
href=\\"javascript: restore_video(this, " + i + ")\\"
|
||||
>click here</a>.
|
||||
</p>
|
||||
";
|
||||
replacement.style.position = "relative";
|
||||
replacement.style.zIndex = "100003000000";
|
||||
replacement.style.fontSize = "1rem";
|
||||
replacement.style.textAlign = "center";
|
||||
replacement.style.verticalAlign = "middle";
|
||||
replacement.style.height = "100%";
|
||||
replacement.style.background = "#101010";
|
||||
replacement.style.color = "white";
|
||||
replacement.style.border = "4px dashed #545454";
|
||||
replacement.style.padding = "2em";
|
||||
replacement.style.margin = "auto";
|
||||
App.all_replacements[i] = replacement;
|
||||
App.backup_videos[i] = video;
|
||||
video.parentNode.replaceChild(replacement, video);
|
||||
}
|
||||
|
||||
function restore_video(obj, index) {
|
||||
obj = App.all_replacements[index];
|
||||
video = App.backup_videos[index];
|
||||
console.log(video);
|
||||
obj.parentNode.replaceChild(video, obj);
|
||||
}
|
||||
|
||||
/** force repainting the video, thanks to:
|
||||
* http://martinwolf.org/2014/06/10/force-repaint-of-an-element-with-javascript/
|
||||
*/
|
||||
var siteHeader = document.getElementById('header');
|
||||
siteHeader.style.display='none';
|
||||
siteHeader.offsetHeight; // no need to store this anywhere, the reference is enough
|
||||
siteHeader.style.display='block';
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
printjs() {
|
||||
js | sed 's,//.*$,,' | tr '\n' ' '
|
||||
}
|
||||
echo "jseval -q $(printjs)" >> "$QUTE_FIFO"
|
||||
|
||||
msg info "Opening $QUTE_URL with mpv"
|
||||
"${video_command[@]}" "$@" "$QUTE_URL"
|
||||
58
pytest.ini
@@ -1,58 +0,0 @@
|
||||
[pytest]
|
||||
addopts = --strict -rfEw --faulthandler-timeout=90 --instafail --pythonwarnings error --benchmark-columns=Min,Max,Median
|
||||
testpaths = tests
|
||||
markers =
|
||||
gui: Tests using the GUI (e.g. spawning widgets)
|
||||
posix: Tests which only can run on a POSIX OS.
|
||||
windows: Tests which only can run on Windows.
|
||||
linux: Tests which only can run on Linux.
|
||||
mac: Tests which only can run on macOS.
|
||||
not_mac: Tests which can not run on macOS.
|
||||
not_frozen: Tests which can't be run if sys.frozen is True.
|
||||
no_xvfb: Tests which can't be run with Xvfb.
|
||||
frozen: Tests which can only be run if sys.frozen is True.
|
||||
integration: Tests which test a bigger portion of code
|
||||
end2end: End to end tests which run qutebrowser as subprocess
|
||||
xfail_norun: xfail the test with out running it
|
||||
ci: Tests which should only run on CI.
|
||||
no_ci: Tests which should not run on CI.
|
||||
qtwebengine_todo: Features still missing with QtWebEngine
|
||||
qtwebengine_skip: Tests not applicable with QtWebEngine
|
||||
qtwebkit_skip: Tests not applicable with QtWebKit
|
||||
qtwebengine_flaky: Tests which are flaky (and currently skipped) with QtWebEngine
|
||||
qtwebengine_mac_xfail: Tests which fail on macOS with QtWebEngine
|
||||
js_prompt: Tests needing to display a javascript prompt
|
||||
this: Used to mark tests during development
|
||||
no_invalid_lines: Don't fail on unparseable lines in end2end tests
|
||||
issue2478: Tests which are broken on Windows with QtWebEngine, https://github.com/qutebrowser/qutebrowser/issues/2478
|
||||
fake_os: Fake utils.is_* to a fake operating system
|
||||
qt_log_level_fail = WARNING
|
||||
qt_log_ignore =
|
||||
^SpellCheck: .*
|
||||
^SetProcessDpiAwareness failed: .*
|
||||
^QWindowsWindow::setGeometry(Dp)?: Unable to set geometry .*
|
||||
^QProcess: Destroyed while process .* is still running\.
|
||||
^"Method "GetAll" with signature "s" on interface "org\.freedesktop\.DBus\.Properties" doesn't exist
|
||||
^"Method \\"GetAll\\" with signature \\"s\\" on interface \\"org\.freedesktop\.DBus\.Properties\\" doesn't exist\\n"
|
||||
^propsReply "Method \\"GetAll\\" with signature \\"s\\" on interface \\"org\.freedesktop\.DBus\.Properties\\" doesn't exist\\n"
|
||||
^nmReply "Method \\"GetDevices\\" with signature \\"\\" on interface \\"org\.freedesktop\.NetworkManager\\" doesn't exist\\n"
|
||||
^"Object path cannot be empty"
|
||||
^virtual void QSslSocketBackendPrivate::transmit\(\) SSL write failed with error: -9805
|
||||
^virtual void QSslSocketBackendPrivate::transmit\(\) SSLRead failed with: -9805
|
||||
^Type conversion already registered from type .*
|
||||
^QNetworkReplyImplPrivate::error: Internal problem, this method must only be called once\.
|
||||
^QWaitCondition: Destroyed while threads are still waiting
|
||||
^QXcbXSettings::QXcbXSettings\(QXcbScreen\*\) Failed to get selection owner for XSETTINGS_S atom
|
||||
^QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to .*
|
||||
^QObject::connect: Cannot connect \(null\)::stateChanged\(QNetworkSession::State\) to QNetworkReplyHttpImpl::_q_networkSessionStateChanged\(QNetworkSession::State\)
|
||||
^QXcbClipboard: Cannot transfer data, no data available
|
||||
^load glyph failed
|
||||
^Error when parsing the netrc file
|
||||
^Image of format '' blocked because it is not considered safe. If you are sure it is safe to do so, you can white-list the format by setting the environment variable QTWEBKIT_IMAGEFORMAT_WHITELIST=
|
||||
^QPainter::end: Painter ended with \d+ saved states
|
||||
^QSslSocket: cannot resolve *
|
||||
^Incompatible version of OpenSSL
|
||||
^QQuickWidget::invalidateRenderControl could not make context current
|
||||
^libpng warning: iCCP: known incorrect sRGB profile
|
||||
^inotify_add_watch(".*") failed: "No space left on device"
|
||||
xfail_strict = true
|
||||
@@ -8,4 +8,3 @@ Exec=qutebrowser %u
|
||||
Terminal=false
|
||||
StartupNotify=false
|
||||
MimeType=text/html;text/xml;application/xhtml+xml;application/xml;application/rdf+xml;image/gif;image/jpeg;image/png;x-scheme-handler/http;x-scheme-handler/https;
|
||||
Keywords=Browser
|
||||