Plugin ideas (and at some point code) for qutebrowser.
Issues in this repository represent ideas for future qutebrowser plugins. At some point, it might also be used as a place for "curated" plugins.
Extension ideas (and at some point code) for qutebrowser
qutebrowser's search-engine functionality is nice, but it would be even nicer if we could parse '!searchengine' as a query to a qutebrowser searchengine. This way, people can keep their bang workflow while either avoiding requests to ddg or overriding their choice of bang wording (for example, I really want !yum git
to search fedora or centos, rather than yummly).
It would be nice to 'tag' searchengines so some of them could be only prefix-based (like the default) and some could be only 'bang' based.
https://doc.qt.io/qt-5/qwebengineurlrequestinfo.html has some additional info (especially ResourceType
) which we should probably expose.
maybe display the list of letters from where you want to start the visual selection identical to how it is done with vim-easymode
reference : https://github.com/easymotion/vim-easymotion
So we can make e.g. qute://pyeval
into an extension.
Not sure yet about how to namespace things - maybe a separate qute-ext://
scheme?
ClickTarget
, JsWorld
, InitContext
Essentially being able to invoke the configured editor on arbitrary files much as is done here: https://gitlab.com/jgkamat/jmatrix/-/blob/master/jmatrix/integrations/qutebrowser.py#L81-102
I want Qutebrowser to go p2p :)
Extensions should be able to add their own settings to qutebrowser.
To move the adblocker out of the core.
The add-on necessary to have before diving into Internet
Think it`s must be officially supported
https://gitlab.com/jgkamat/jmatrix
Users should be able to blacklist extensions (even builtin components) from loading.
Possibility for specific sites, sessions or modes (e. g. private mode) to choose wich JS to block or JS from which site, resp.
Getting all windows, getting tabs from them, signals for new windows/tabs etc.
Should probably allow moving most :tab-*
commands to use the tab API.
The Reddit Enhancement Suite extension is the only extension still keeping me on Firefox. The other extensions are fulfilled by other programs like OpenVPN. So, if it is possible to port RES, it would be really nice.
Just like Video DownloadHelper. This is already in the plugin ideas section in qutebrowser/qutebrowser#30 (comment), but I thought some people might actually check this repo only so decided to open an issue here as well.
Would be really nice if one could perform custom commands on the urls, such as open them in a player such as mpv.
Hello,
It would be great to have a bitwarden extension available for the Qute browser users. It is one of the most popular password managers out there.
It would be nice to have a general purpose time tracker in qutebrowser. Some ideas:
<host> <time>
:buffer
to sort buffers by their "hotness"I'm not sure if there's a good 'time vizualizer' that can visualize files that we create (as it would be a waste of time to do it ourselves). Maybe we can generate a fake 'profile' that you could view in a flamechart viewer (where the TLD is the top level function which 'calls' subdomains).
I love QuteBrowser but also love 1Password. 1Password has plugins for Chrome, Firefox, and Safari. Could we write one for QuteBrowser??
One of the biggest quality-of-life improvements for me in browsers is Real-Time Tab Sync.
I don't want Qutebrowser to get in the business of syncing state between devices. I have Syncthing for that and it does a great job.
But it would be wonderful if Qutebrowser one day had an extension that at least writes the relevant state to a folder. Ideally in a way that works well with Syncthing. So for example, writing a list of open URLs into a file would regularly cause Syncthing sync conflicts, but writing each open URL into its own file would be great for Syncthing.
It would be really nice, but probably not strictly necessary, for the extension to also watch that folder for changes (with f.e. inotify on Linux, etc) and open/close tabs accordingly (near as I can tell, it would be possible to design the state folder structure/contents so that watching for changes and syncing the opening of tabs could be done by an external program... I haven't exhaustively thought if syncing the closing of tabs could be handled reasonably well by an external program or not).
I intend to eventually write up a more concrete+complete design for this, but not sure when I'll have the time to do that.
Likely it's already possible to pass a completion function to a new command, but it should be documented.
please close, wrong repo
First approach with the "components" package shipped with qutebrowser:
From 8dca7e07e98cb4e724ac1f82c7e3de0be8592c3b Mon Sep 17 00:00:00 2001
From: Florian Bruhin <[email protected]>
Date: Mon, 10 Dec 2018 09:38:23 +0100
Subject: [PATCH 1/3] Load components dynamically
---
qutebrowser/app.py | 4 ++--
qutebrowser/extensions/__init__.py | 0
qutebrowser/extensions/loader.py | 35 ++++++++++++++++++++++++++++++
qutebrowser/utils/log.py | 3 ++-
scripts/dev/run_vulture.py | 3 +++
scripts/dev/src2asciidoc.py | 2 ++
6 files changed, 44 insertions(+), 3 deletions(-)
create mode 100644 qutebrowser/extensions/__init__.py
create mode 100644 qutebrowser/extensions/loader.py
diff --git a/qutebrowser/app.py b/qutebrowser/app.py
index 6c948e10c8..65c7395eb0 100644
--- a/qutebrowser/app.py
+++ b/qutebrowser/app.py
@@ -68,6 +68,7 @@
from qutebrowser.browser.network import proxy
from qutebrowser.browser.webkit import cookies, cache
from qutebrowser.browser.webkit.network import networkmanager
+from qutebrowser.extensions import loader
from qutebrowser.keyinput import macros
from qutebrowser.mainwindow import mainwindow, prompt
from qutebrowser.misc import (readline, ipc, savemanager, sessions,
@@ -77,8 +78,6 @@
usertypes, standarddir, error, qtutils)
# pylint: disable=unused-import
# We import those to run the cmdutils.register decorators.
-from qutebrowser.components import (scrollcommands, caretcommands,
- zoomcommands, misccommands)
from qutebrowser.mainwindow.statusbar import command
from qutebrowser.misc import utilcmds
# pylint: enable=unused-import
@@ -166,6 +165,7 @@ def init(args, crash_handler):
qApp.setQuitOnLastWindowClosed(False)
_init_icon()
+ loader.load_components()
try:
_init_modules(args, crash_handler)
except (OSError, UnicodeDecodeError, browsertab.WebTabError) as e:
diff --git a/qutebrowser/extensions/__init__.py b/qutebrowser/extensions/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/qutebrowser/extensions/loader.py b/qutebrowser/extensions/loader.py
new file mode 100644
index 0000000000..9b5aadd25c
--- /dev/null
+++ b/qutebrowser/extensions/loader.py
@@ -0,0 +1,35 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+
+# Copyright 2018 Florian Bruhin (The Compiler) <[email protected]>
+#
+# 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/>.
+
+"""Loader for qutebrowser extensions."""
+
+import pkgutil
+
+from qutebrowser import components
+from qutebrowser.utils import log
+
+
+def load_components() -> None:
+ """Load everything from qutebrowser.components."""
+ for info in pkgutil.walk_packages(components.__path__):
+ if info.ispkg:
+ continue
+ log.extensions.debug("Importing {}".format(info.name))
+ loader = info.module_finder.find_module(info.name)
+ loader.load_module(info.name)
diff --git a/qutebrowser/utils/log.py b/qutebrowser/utils/log.py
index bbc0255158..115c53352f 100644
--- a/qutebrowser/utils/log.py
+++ b/qutebrowser/utils/log.py
@@ -137,6 +137,7 @@ def vdebug(self, msg, *args, **kwargs):
network = logging.getLogger('network')
sql = logging.getLogger('sql')
greasemonkey = logging.getLogger('greasemonkey')
+extensions = logging.getLogger('extensions')
LOGGER_NAMES = [
'statusbar', 'completion', 'init', 'url',
@@ -146,7 +147,7 @@ def vdebug(self, msg, *args, **kwargs):
'js', 'qt', 'rfc6266', 'ipc', 'shlexer',
'save', 'message', 'config', 'sessions',
'webelem', 'prompt', 'network', 'sql',
- 'greasemonkey'
+ 'greasemonkey', 'extensions',
]
diff --git a/scripts/dev/run_vulture.py b/scripts/dev/run_vulture.py
index f3217694ee..7874f6a796 100755
--- a/scripts/dev/run_vulture.py
+++ b/scripts/dev/run_vulture.py
@@ -30,6 +30,7 @@
import vulture
import qutebrowser.app # pylint: disable=unused-import
+from qutebrowser.extensions import loader
from qutebrowser.misc import objects
from qutebrowser.utils import utils
from qutebrowser.browser.webkit import rfc6266
@@ -43,6 +44,8 @@
def whitelist_generator(): # noqa
"""Generator which yields lines to add to a vulture whitelist."""
+ loader.load_components()
+
# qutebrowser commands
for cmd in objects.commands.values():
yield utils.qualname(cmd.handler)
diff --git a/scripts/dev/src2asciidoc.py b/scripts/dev/src2asciidoc.py
index ba4e9b69c7..f0536c045b 100755
--- a/scripts/dev/src2asciidoc.py
+++ b/scripts/dev/src2asciidoc.py
@@ -35,6 +35,7 @@
# We import qutebrowser.app so all @cmdutils-register decorators are run.
import qutebrowser.app
from qutebrowser import qutebrowser, commands
+from qutebrowser.extensions import loader
from qutebrowser.commands import argparser
from qutebrowser.config import configdata, configtypes
from qutebrowser.utils import docutils, usertypes
@@ -549,6 +550,7 @@ def regenerate_cheatsheet():
def main():
"""Regenerate all documentation."""
utils.change_cwd()
+ loader.load_components()
print("Generating manpage...")
regenerate_manpage('doc/qutebrowser.1.asciidoc')
print("Generating settings help...")
From f0ea11b8e2f8f0307a32627e4b5614965996e3ae Mon Sep 17 00:00:00 2001
From: Florian Bruhin <[email protected]>
Date: Mon, 10 Dec 2018 10:06:07 +0100
Subject: [PATCH 2/3] Add types to extensions.loader
---
mypy.ini | 4 ++++
qutebrowser/extensions/loader.py | 18 +++++++++++++-----
2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/mypy.ini b/mypy.ini
index 4526e4e48c..8fb8d89ae3 100644
--- a/mypy.ini
+++ b/mypy.ini
@@ -73,3 +73,7 @@ disallow_incomplete_defs = True
[mypy-qutebrowser.components.*]
disallow_untyped_defs = True
disallow_incomplete_defs = True
+
+[mypy-qutebrowser.extensions.*]
+disallow_untyped_defs = True
+disallow_incomplete_defs = True
diff --git a/qutebrowser/extensions/loader.py b/qutebrowser/extensions/loader.py
index 9b5aadd25c..9674ad7079 100644
--- a/qutebrowser/extensions/loader.py
+++ b/qutebrowser/extensions/loader.py
@@ -19,7 +19,9 @@
"""Loader for qutebrowser extensions."""
+import importlib.abc
import pkgutil
+import types
from qutebrowser import components
from qutebrowser.utils import log
@@ -27,9 +29,15 @@
def load_components() -> None:
"""Load everything from qutebrowser.components."""
- for info in pkgutil.walk_packages(components.__path__):
- if info.ispkg:
+ for finder, name, ispkg in pkgutil.walk_packages(components.__path__):
+ if ispkg:
continue
- log.extensions.debug("Importing {}".format(info.name))
- loader = info.module_finder.find_module(info.name)
- loader.load_module(info.name)
+ _load_module(finder, name)
+
+
+def _load_module(finder: importlib.abc.PathEntryFinder,
+ name: str) -> types.ModuleType:
+ log.extensions.debug("Importing {}".format(name))
+ loader = finder.find_module(name)
+ assert loader is not None
+ return loader.load_module(name)
From a17dde31964c3c81cbeb4c33c036d9a86303d81e Mon Sep 17 00:00:00 2001
From: Florian Bruhin <[email protected]>
Date: Mon, 10 Dec 2018 10:26:25 +0100
Subject: [PATCH 3/3] Add components to pyinstaller hiddenimports
---
misc/qutebrowser.spec | 11 ++++++++++-
qutebrowser/extensions/loader.py | 27 +++++++++++++++++++++------
2 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/misc/qutebrowser.spec b/misc/qutebrowser.spec
index ff1b10577a..b40172754f 100644
--- a/misc/qutebrowser.spec
+++ b/misc/qutebrowser.spec
@@ -6,6 +6,8 @@ import os
sys.path.insert(0, os.getcwd())
from scripts import setupcommon
+from qutebrowser.extensions import loader
+
block_cipher = None
@@ -27,6 +29,13 @@ def get_data_files():
return data_files
+def get_hidden_imports():
+ imports = ['PyQt5.QtOpenGL', 'PyQt5._QOpenGLFunctions_2_0']
+ for info in loader.walk_components():
+ imports.append('qutebrowser.components.' + info.name)
+ return imports
+
+
setupcommon.write_git_file()
@@ -42,7 +51,7 @@ a = Analysis(['../qutebrowser/__main__.py'],
pathex=['misc'],
binaries=None,
datas=get_data_files(),
- hiddenimports=['PyQt5.QtOpenGL', 'PyQt5._QOpenGLFunctions_2_0'],
+ hiddenimports=get_hidden_imports(),
hookspath=[],
runtime_hooks=[],
excludes=['tkinter'],
diff --git a/qutebrowser/extensions/loader.py b/qutebrowser/extensions/loader.py
index 9674ad7079..d6fdc675ee 100644
--- a/qutebrowser/extensions/loader.py
+++ b/qutebrowser/extensions/loader.py
@@ -22,22 +22,37 @@
import importlib.abc
import pkgutil
import types
+import typing
+
+import attr
from qutebrowser import components
from qutebrowser.utils import log
+@attr.s
+class ComponentInfo:
+
+ name = attr.ib() # type: str
+ finder = attr.ib() # type: importlib.abc.PathEntryFinder
+
+
def load_components() -> None:
"""Load everything from qutebrowser.components."""
+ for info in walk_components():
+ _load_component(info)
+
+
+def walk_components() -> typing.Iterator[ComponentInfo]:
+ """Yield ComponentInfo objects for all modules."""
for finder, name, ispkg in pkgutil.walk_packages(components.__path__):
if ispkg:
continue
- _load_module(finder, name)
+ yield ComponentInfo(name=name, finder=finder)
-def _load_module(finder: importlib.abc.PathEntryFinder,
- name: str) -> types.ModuleType:
- log.extensions.debug("Importing {}".format(name))
- loader = finder.find_module(name)
+def _load_component(info: ComponentInfo) -> types.ModuleType:
+ log.extensions.debug("Importing {}".format(info.name))
+ loader = info.finder.find_module(info.name)
assert loader is not None
- return loader.load_module(name)
+ return loader.load_module(info.name)
However, that fails to find any modules on macOS/Windows with the frozen package. On macOS, components.__path__
shows /Volumes/qutebrowser/qutebrowser.app/Contents/MacOS/qutebrowser/components
with qutebrowser
being the executable (i.e., that path doesn't exist at all). As a result, pkgutil.walk_packages(components.__path__)
doesn't yield anything.
I'm wondering if something like GhostText could be implimented into qutebrowser--or is this something that would be too heavy or impossible for the project?
It would be very nice to have an api to provide advice to various functions, for example, for yank.
Eg:
https://github.com/qutebrowser/qutebrowser
-> [email protected]:qutebrowser/qutebrowser.git
https://github.com/qutebrowser/qutebrowser-extensions/issues/18
-> #18
(or qutebrowser/qutebrowser-extensions#18
)https://github.com/qutebrowser/qutebrowser
-> github.com/qutebrowser/qutebrowser
http://no-www.org/
-> http://www.no-www.org/
https://badssl.com/
-> http://badssl.com/
https://github.com/qutebrowser/qutebrowser
-> https://com.github/qutebrowser/qutebrowser
This would also be useful for paste and/or opened links:
https://www.reddit.com/
-> https://www.old.reddit.com/
https://www.facebook.com/
-> https://mbasic.facebook.com/
https://twitter.com/
-> https://mobile.twitter.com/
https://github.com/qutebrowser/qutebrowser
-> https://gitlab.com/qutebrowser/qutebrowser
To make various password userscripts work without everyone needing its own logic.
Maybe the selecting part could be separate, though, via some more generic completion integration.
To move the adblocker out of the core.
When using more than one keyboard layout within QB, writing text can be a hassle. Vim also has such problems, as well as several solutions, such as embedded keymap/iminsert settings, or external plugin vim-xkbswitch (you can read it's readme to get a better idea of what I'm talking about).
Basically, I wish to port vim-xkbswitch to qutebrowser-extensions. Or, at least, have some substitution for it.
It seems like minimal requirement is API should provide means to connect to mode_manager
's signals entered
and left
for this to work. Probably also some other changes to support helping in //?-search.
When using emacs-style buffer management instead of tabs, it can be useful to have a way to automatically-clean up unused buffers.
A midnight mode plugin would emulate 'midnight-mode' in emacs, which:
<x>
days.The main usecase obviously being qutenyan!
If a request type doesn't support redirections, we fail with: qutebrowser.extensions.interceptors.RedirectFailedException: Request method does not support redirection.
However, the exception type is not exposed via the API. Also, there should probably be something like info.redirect(url, only_supported=True)
which automatically silences those errors.
It would be nice to have a better adblock solution where you can whitelist and blacklist sites as well as blocking ads in the content of the site maybe a proxy.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.