[packages/uzbl] - push proper patch

arekm arekm at pld-linux.org
Sun Dec 8 17:12:28 CET 2013


commit 099006da4d6c9d498728aa7ec4ffe6727ce41ab1
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date:   Sun Dec 8 17:12:25 2013 +0100

    - push proper patch

 uzbl-build.patch |    11 +
 uzbl-git.patch   | 11204 -----------------------------------------------------
 2 files changed, 11 insertions(+), 11204 deletions(-)
---
diff --git a/uzbl-build.patch b/uzbl-build.patch
new file mode 100644
index 0000000..1aaabee
--- /dev/null
+++ b/uzbl-build.patch
@@ -0,0 +1,11 @@
+--- uzbl-2013.12.08/Makefile~	2013-12-08 16:48:28.000000000 +0100
++++ uzbl-2013.12.08/Makefile	2013-12-08 17:07:53.206953656 +0100
+@@ -189,7 +189,7 @@
+ 	install -m755 uzbl-core $(INSTALLDIR)/bin/uzbl-core
+ 
+ install-event-manager: install-dirs
+-	$(PYTHON) setup.py install --prefix=$(PREFIX) --install-scripts=$(INSTALLDIR)/bin $(PYINSTALL_EXTRA)
++	$(PYTHON) setup.py install --prefix=$(PREFIX) --root=$(DESTDIR) --install-scripts=$(PREFIX)/bin $(PYINSTALL_EXTRA)
+ 
+ install-uzbl-browser: install-dirs install-uzbl-core install-event-manager
+ 	sed 's#^PREFIX=.*#PREFIX=$(RUN_PREFIX)#' < bin/uzbl-browser > $(INSTALLDIR)/bin/uzbl-browser
diff --git a/uzbl-git.patch b/uzbl-git.patch
deleted file mode 100644
index 8d4610a..0000000
--- a/uzbl-git.patch
+++ /dev/null
@@ -1,11204 +0,0 @@
-diff --git a/.gitignore b/.gitignore
-index 8c08dc0..092909f 100644
---- a/.gitignore
-+++ b/.gitignore
-@@ -1,4 +1,5 @@
- uzbl-core
-+local.mk
- *.o
- *.lo
- *.pyc
-@@ -6,3 +7,4 @@ uzbl-core
- *~
- tags
- sandbox
-+/build
-diff --git a/AUTHORS b/AUTHORS
-index b3ce2e2..22d3c9b 100644
---- a/AUTHORS
-+++ b/AUTHORS
-@@ -46,6 +46,7 @@ In alphabetical order:
-     Gregor Uhlenheuer (kongo2002) <kongo2002 at googlemail.com> - uzbl vim syntax & related files
-     Helmut Grohne (helmut) - move void **ptr to union, various fixes
-     Henri Kemppainen (DuClare) <email is akarinotengoku AT THE DOMAIN OF gmail.com> - many contributions, mostly old handler code
-+    Håkan Jerning - uzbl-tabbed: autosave_session patch
-     Igor Bogomazov - mouse ptr events
-     Jake Probst <jake.probst at gmail.com> - uzbl_tabbed: multiline tablist, new window opening patches
-     James Campos (aeosynth) <james.r.campos at gmail.com> - Re-orderable gtk notebook tabs in uzbl-tabbed
-diff --git a/Makefile b/Makefile
-index a11fc8d..ba74e57 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1,25 +1,53 @@
-+# Create a local.mk file to store default local settings to override the
-+# defaults below.
-+include $(wildcard local.mk)
-+
- # packagers, set DESTDIR to your "package directory" and PREFIX to the prefix you want to have on the end-user system
- # end-users who build from source: don't care about DESTDIR, update PREFIX if you want to
- # RUN_PREFIX : what the prefix is when the software is run. usually the same as PREFIX
--PREFIX?=/usr/local
--INSTALLDIR?=$(DESTDIR)$(PREFIX)
--DOCDIR?=$(INSTALLDIR)/share/uzbl/docs
--RUN_PREFIX?=$(PREFIX)
-+PREFIX     ?= /usr/local
-+INSTALLDIR ?= $(DESTDIR)$(PREFIX)
-+DOCDIR     ?= $(INSTALLDIR)/share/uzbl/docs
-+RUN_PREFIX ?= $(PREFIX)
-+
-+ENABLE_WEBKIT2 ?= no
-+ENABLE_GTK3    ?= auto
-+
-+PYTHON=python3
-+PYTHONV=$(shell $(PYTHON) --version | sed -n /[0-9].[0-9]/p)
-+COVERAGE=$(shell which coverage)
-+
-+# --- configuration ends here ---
-+
-+ifeq ($(ENABLE_WEBKIT2),auto)
-+ENABLE_WEBKIT2 := $(shell pkg-config --exists webkit2gtk-3.0 && echo yes)
-+endif
- 
--# use GTK3-based webkit when it is available
--USE_GTK3 = $(shell pkg-config --exists gtk+-3.0 webkitgtk-3.0 && echo 1)
-+ifeq ($(ENABLE_GTK3),auto)
-+ENABLE_GTK3 := $(shell pkg-config --exists gtk+-3.0 && echo yes)
-+endif
- 
--ifeq ($(USE_GTK3),1)
--	REQ_PKGS += gtk+-3.0 webkitgtk-3.0 javascriptcoregtk-3.0
--	CPPFLAGS = -DG_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED
-+ifeq ($(ENABLE_WEBKIT2),yes)
-+REQ_PKGS += 'webkit2gtk-3.0 >= 1.2.4' javascriptcoregtk-3.0
-+CPPFLAGS += -DUSE_WEBKIT2
-+# WebKit2 requires GTK3
-+ENABLE_GTK3    := yes
-+else
-+ifeq ($(ENABLE_GTK3),yes)
-+REQ_PKGS += 'webkitgtk-3.0 >= 1.2.4' javascriptcoregtk-3.0
- else
--	REQ_PKGS += gtk+-2.0 webkit-1.0 javascriptcoregtk-1.0
--	CPPFLAGS =
-+REQ_PKGS += 'webkit-1.0 >= 1.2.4' javascriptcoregtk-1.0
-+endif
- endif
- 
--# --- configuration ends here ---
-+ifeq ($(ENABLE_GTK3),yes)
-+REQ_PKGS += gtk+-3.0
-+CPPFLAGS += -DG_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED
-+else
-+REQ_PKGS += gtk+-2.0
-+endif
- 
--REQ_PKGS += libsoup-2.4 gthread-2.0 glib-2.0
-+REQ_PKGS += 'libsoup-2.4 >= 2.30' gthread-2.0 glib-2.0
- 
- ARCH:=$(shell uname -m)
- 
-@@ -33,10 +61,11 @@ LDLIBS:=$(shell pkg-config --libs $(REQ_PKGS) x11)
- 
- CFLAGS += -std=c99 $(PKG_CFLAGS) -ggdb -W -Wall -Wextra -pedantic -pthread
- 
--SRC = $(wildcard src/*.c)
-+SRC  = $(wildcard src/*.c)
- HEAD = $(wildcard src/*.h)
- OBJ  = $(foreach obj, $(SRC:.c=.o),  $(notdir $(obj)))
- LOBJ = $(foreach obj, $(SRC:.c=.lo), $(notdir $(obj)))
-+PY = $(wildcard uzbl/*.py uzbl/plugins/*.py)
- 
- all: uzbl-browser
- 
-@@ -46,7 +75,13 @@ ${OBJ}: ${HEAD}
- 
- uzbl-core: ${OBJ}
- 
--uzbl-browser: uzbl-core
-+uzbl-browser: uzbl-core uzbl-event-manager
-+
-+build: ${PY}
-+	$(PYTHON) setup.py build
-+
-+.PHONY: uzbl-event-manager
-+uzbl-event-manager: build
- 
- # the 'tests' target can never be up to date
- .PHONY: tests
-@@ -61,38 +96,43 @@ tests: ${LOBJ} force
- 	$(CC) -shared -Wl ${LOBJ} -o ./tests/libuzbl-core.so
- 	cd ./tests/; $(MAKE)
- 
-+test-event-manager: force
-+	${PYTHON} -m unittest discover tests/event-manager -v
-+
-+coverage-event-manager: force
-+	${PYTHON} ${COVERAGE} erase
-+	${PYTHON} ${COVERAGE} run -m unittest discover tests/event-manager
-+	${PYTHON} ${COVERAGE} html ${PY}
-+	# Hmm, I wonder what a good default browser would be
-+	uzbl-browser htmlcov/index.html
-+
- test-uzbl-core: uzbl-core
- 	./uzbl-core --uri http://www.uzbl.org --verbose
- 
- test-uzbl-browser: uzbl-browser
- 	./bin/uzbl-browser --uri http://www.uzbl.org --verbose
- 
--test-uzbl-core-sandbox: uzbl-core
--	make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-uzbl-core
--	make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-example-data
--	cp -np ./misc/env.sh ./sandbox/env.sh
-+test-uzbl-core-sandbox: sandbox uzbl-core sandbox-install-uzbl-core sandbox-install-example-data
- 	. ./sandbox/env.sh && uzbl-core --uri http://www.uzbl.org --verbose
- 	make DESTDIR=./sandbox uninstall
- 	rm -rf ./sandbox/usr
- 
--test-uzbl-browser-sandbox: uzbl-browser
--	make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-uzbl-browser
--	make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-example-data
--	cp -np ./misc/env.sh ./sandbox/env.sh
--	-. ./sandbox/env.sh && uzbl-event-manager restart -avv
-+test-uzbl-browser-sandbox: sandbox uzbl-browser sandbox-install-uzbl-browser sandbox-install-example-data
-+	. ./sandbox/env.sh && ${PYTHON} -S `which uzbl-event-manager` restart -navv &
- 	. ./sandbox/env.sh && uzbl-browser --uri http://www.uzbl.org --verbose
--	. ./sandbox/env.sh && uzbl-event-manager stop -ivv
-+	. ./sandbox/env.sh && ${PYTHON} -S `which uzbl-event-manager` stop -vv -o /dev/null
- 	make DESTDIR=./sandbox uninstall
- 	rm -rf ./sandbox/usr
- 
--test-uzbl-tabbed-sandbox: uzbl-browser
--	make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-uzbl-browser
--	make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-uzbl-tabbed
--	make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-example-data
--	cp -np ./misc/env.sh ./sandbox/env.sh
--	-. ./sandbox/env.sh && uzbl-event-manager restart -avv
-+test-uzbl-tabbed-sandbox: sandbox uzbl-browser sandbox-install-uzbl-browser sandbox-install-uzbl-tabbed sandbox-install-example-data
-+	. ./sandbox/env.sh && ${PYTHON} -S `which uzbl-event-manager` restart -avv
- 	. ./sandbox/env.sh && uzbl-tabbed
--	. ./sandbox/env.sh && uzbl-event-manager stop -ivv
-+	. ./sandbox/env.sh && ${PYTHON} -S `which uzbl-event-manager` stop -avv
-+	make DESTDIR=./sandbox uninstall
-+	rm -rf ./sandbox/usr
-+
-+test-uzbl-event-manager-sandbox: sandbox uzbl-browser sandbox-install-uzbl-browser sandbox-install-example-data
-+	. ./sandbox/env.sh && ${PYTHON} -S `which uzbl-event-manager` restart -navv
- 	make DESTDIR=./sandbox uninstall
- 	rm -rf ./sandbox/usr
- 
-@@ -102,18 +142,44 @@ clean:
- 	find ./examples/ -name "*.pyc" -delete
- 	cd ./tests/; $(MAKE) clean
- 	rm -rf ./sandbox/
-+	$(PYTHON) setup.py clean
- 
- strip:
- 	@echo Stripping binary
- 	@strip uzbl-core
- 	@echo ... done.
- 
-+SANDBOXOPTS=\
-+	DESTDIR=./sandbox\
-+	RUN_PREFIX=`pwd`/sandbox/usr/local\
-+	PYINSTALL_EXTRA='--prefix=./sandbox/usr/local --install-scripts=./sandbox/usr/local/bin'
-+
-+sandbox: misc/env.sh
-+	mkdir -p sandbox/${PREFIX}/lib64
-+	cp -p misc/env.sh sandbox/env.sh
-+	test -e sandbox/${PREFIX}/lib || ln -s lib64 sandbox/${PREFIX}/lib
-+
-+sandbox-install-uzbl-browser:
-+	make ${SANDBOXOPTS} install-uzbl-browser
-+
-+sandbox-install-uzbl-tabbed:
-+	make ${SANDBOXOPTS} install-uzbl-tabbed
-+
-+sandbox-install-uzbl-core:
-+	make ${SANDBOXOPTS} install-uzbl-core
-+
-+sandbox-install-event-manager:
-+	make ${SANDBOXOPTS} install-event-manager
-+
-+sandbox-install-example-data:
-+	make ${SANDBOXOPTS} install-example-data
-+
- install: install-uzbl-core install-uzbl-browser install-uzbl-tabbed
- 
- install-dirs:
- 	[ -d "$(INSTALLDIR)/bin" ] || install -d -m755 $(INSTALLDIR)/bin
- 
--install-uzbl-core: all install-dirs
-+install-uzbl-core: uzbl-core install-dirs
- 	install -d $(INSTALLDIR)/share/uzbl/
- 	install -d $(DOCDIR)
- 	install -m644 docs/* $(DOCDIR)/
-@@ -123,8 +189,7 @@ install-uzbl-core: all install-dirs
- 	install -m755 uzbl-core $(INSTALLDIR)/bin/uzbl-core
- 
- install-event-manager: install-dirs
--	sed "s#^PREFIX = .*#PREFIX = '$(RUN_PREFIX)'#" < bin/uzbl-event-manager > $(INSTALLDIR)/bin/uzbl-event-manager
--	chmod 755 $(INSTALLDIR)/bin/uzbl-event-manager
-+	$(PYTHON) setup.py install --prefix=$(PREFIX) --install-scripts=$(INSTALLDIR)/bin $(PYINSTALL_EXTRA)
- 
- install-uzbl-browser: install-dirs install-uzbl-core install-event-manager
- 	sed 's#^PREFIX=.*#PREFIX=$(RUN_PREFIX)#' < bin/uzbl-browser > $(INSTALLDIR)/bin/uzbl-browser
-diff --git a/README b/README
-index b124fb4..5241aba 100644
---- a/README
-+++ b/README
-@@ -252,18 +252,42 @@ The following commands are recognized:
-   - Open the print dialog.
- * `include <file>`
-   - Read contents of `<file>` and interpret as a set of `uzbl` commands.
--* `show_inspector`
--  - Show the WebInspector
-+* `inspector <show | hide | coord <x> <y> | node <node-spec>>`
-+  - Control the inspector. The `coord` command coordinates are relative to the
-+    viewport, not the page. The `node` subcommand requires webkitgtk >=
-+    1.3.17.
-+* `spell_checker <ignore <word>... | learn <word>... | autocorrect <word> | guesses <word>>`
-+  - Control the spell checker. Requires webkitgtk >= 1.5.1.
- * `add_cookie <domain> <path> <name> <value> <scheme> <expires>`
-   - Adds a new cookie to the cookie jar
- * `delete_cookie <domain> <path> <name> <value> [<scheme> <expires>]`
-   - Deletes a matching cookie from the cookie jar. scheme and expire time
--	  is currently not considered when matching.
-+    is currently not considered when matching.
- * `clear_cookies`
-   - Clears all cookies from the cookie jar
- * `download <uri> [<destination path>]`
-   - Starts a download using the given uri. A destination file path can be given
-     to specify where the download should be written to.
-+* `auth <uniqueid> <username> <password>`
-+  - Authenticate as `<username>` with `<password>` for the previously issued
-+    challenge with the id `<uniqueid>`. authenticating for a invalid id or one
-+    expired one has no effect.
-+* `snapshot <path>`
-+  - Saves an image of the visible page as a PNG to the given path. Only available
-+    with webkitgtk >= 1.9.6. This is not in webkit2gtk.
-+* `load <string> <uri> [<baseuri>]`
-+  - Load a string as text/html with the given uri. If given, all links will be
-+    assumed relative to baseuri. Requires webkit2gtk >= 1.9.90.
-+* `save [<format> [<path>]]`
-+  - Saves the current page to a file in a given format (currently only "mhtml"
-+    is supported). Requires webkit2gtk >= 1.9.90.
-+* `remove_all_db`
-+  - Removes all of the web databases from the current database directory path.
-+* `plugin_refresh`
-+  - Refreshes the plugin database. Requires webkitgtk >= 1.3.8.
-+* `plugin_toggle [<plugin name> [<plugin name>...]]`
-+  - Toggles whether the plugins named as arguments are enabled. No arguments is
-+    interpreted as "all plugins". Requires webkitgtk >= 1.3.8.
- 
- ### VARIABLES AND CONSTANTS
- 
-@@ -283,8 +307,10 @@ file).
- 
- * `uri`: The URI of the current page. (callback: load the uri)
- * `verbose`: Controls the verbosity printed to `stdout`.
-+* `inject_text`: Inject an text string, navigating to the URI "about:blank" and
-+  rendering the text string given. Only available in webkit2gtk.
- * `inject_html`: Inject an HTML string, navigating to the URI "about:blank" and
--  rendering the HTML sting given.
-+  rendering the HTML string given.
- * `geometry`: Geometry and position of the Uzbl window. Format is
-   "<width>x<height>+<x-offset>+<y-offset>".
- * `keycmd`: Holds the input buffer (callback: update input buffer).
-@@ -333,11 +359,16 @@ file).
- * `useragent`: The User-Agent to send to the browser, expands variables in its
-   definition.
- * `accept_languages`: The Accept-Language header to send with HTTP requests.
-+* `transparent`: If set to 1, the background of the view will be transparent
-+  (default 0).
-+* `view_mode`: The view mode for webkit. One of: "windowed", "floating",
-+  "fullscreen", "maximized", or "minimized". Requires webkitgtk >= 1.3.4.
- * `zoom_level`: The factor by which elements in the page are scaled with respect
-   to their original size. Setting this will resize the currently displayed page.
- * `zoom_type`: Whether to use "full-content" zoom (defaults to true). With
-   full-content zoom on, all page content, not just text, is zoomed. When
--  full-content zoom is off, only the text of a page is zoomed.
-+  full-content zoom is off, only the text of a page is zoomed. This is
-+  unavailable with webkit2gtk. Use `zoom_text_only` instead.
- * `font_size`: The default font size.
- * `default_font_family`: The default font family used to display text.
- * `monospace_font_family`: The default font family used to display monospace
-@@ -349,7 +380,6 @@ file).
- * `fantasy_font_family`: The default Fantasy font family used to display text.
- * `monospace_size`: The default size of monospaced font (default 1).
- * `minimum_font_size`: The minimum font size used to display text (default 1).
--* `enable_pagecache`: Enable the webkit pagecache (it caches rendered pages for a speedup when you go back or forward in history) (default 0).
- * `enable_plugins`: Disable embedded plugin objects (default 0).
- * `enable_scripts`: Disable embedded scripting languages (default 0).
- * `autoload_images`: Automatically load images (default 1).
-@@ -360,25 +390,109 @@ file).
-   `en_CA` or `pt_BR`) to be used for spell checking, separated by commas.
-   Defaults to the value returned by `gtk_get_default_language`.
- * `enable_private`: Whether to enable private browsing mode (default 0).
-+* `cookie_policy`: If set to 0, all cookies are accepted, if set to 1, all
-+  cookies are rejected, and 2 rejects third party cookies (default 0).
- * `print_backgrounds`: Print background images? (default 0).
- * `stylesheet_uri`: Use this to override the pagelayout with a custom
-   stylesheet.
- * `resizable_text_areas`: Whether text areas can be resized (default 0).
- * `default_encoding`: The default text encoding (default "iso-8859-1").
--* `current_encoding`: This can be set to force a text encoding.
-+* `custom_encoding`: This can be set to force a text encoding. (Used to be
-+  `current_encoding` which is now read-only).
- * `enforce_96_dpi`: Enforce a resolution of 96 DPI (default 1).
-+* `editable`: Whether the page can be edited or not (default 0).
- * `caret_browsing`: Whether the caret is enabled in the text portion of pages
-   (default 0).
- * `enable_cross_file_access`: Whether a page loaded from a `file://` URI can
-   access the contents of other `file://` URIs. (default 0).
- * `follow_hint_keys`: keys for keyboard-based navigation and link
--   highlighting
-+  highlighting
- * `handle_multi_click`: If set to 1, event handlers attached to `2Button*`
--   and `3Button*` bindings will only be used instead of the default actions in
--   WebKit (default 0).
-+  and `3Button*` bindings will only be used instead of the default actions in
-+  WebKit (default 0).
- * `ssl_ca_file`: File that contains CA certificates.
- * `ssl_verify`: If set to 1, uzbl won't connect to "https" url unless it can
-    validate certificate presented by remote server against `ssl_ca_file`.
-+* `enable_builtin_auth`: Enable WebKits builtin authentication handler
-+* `enable_java_applet`: If set to 1, support for Java <applet> tags will be
-+  enabled (default 1).
-+* `enable_database`: If set to 1, support for HTML5 client-side SQL databases
-+  will be enabled (default 1).
-+* `enable_local_storage`: If set to 1, websites will be able to store data
-+  locally (default 1).
-+* `enable_pagecache`: If set to 1, uzbl will store previously visited pages for
-+  faster access (the cache is local to each uzbl instance) (default 0).
-+* `enable_offline_app_cache`: If set to 1, web applications may be cached locally
-+  for offline use (default 1).
-+* `enable_universal_file_access`: If set to 1, allow `file://` URIs to access
-+  all pages (default 0).
-+* `enable_hyperlink_auditing`: If set to 1, the `ping` attribute on anchors will
-+  be supported (default 0).
-+* `zoom_step`: The change in the zoon level when zooming (default 0.1).
-+* `auto_resize_window`: If set to 1, allow web pages to change window dimensions
-+  (default 0).
-+* `enable_spatial_navigation`: If set to 1, the arrow keys in `Ins` mode will
-+  navigate between form elements (default 0).
-+* `editing_behavior`: When set to 0, emulate Mac behavior in text fields, 1
-+  for Windows behavior, and 2 for *nix behavior (the default).
-+* `enable_tab_cycle`: If set to 1, the `Tab` key cycles between elements on
-+  the page (default 1).
-+* `default_context_menu`: If set to 0, do not cause context menus to appear when
-+  right clicking (default 1).
-+* `enable_site_workarounds`: If set to 1, enable filters to help unbreak
-+  certain websites (default 0).
-+* `javascript_clipboard`: If set to 1, JavaScript may access the clipboard
-+  (default 0). Requires webkitgtk >= 1.3.0.
-+* `javascript_dom_paste`: If set to 1, JavaScript will able to paste from the
-+  clipboard (default 0).
-+* `enable_frame_flattening`: If set to 1, flatten all frames into a single
-+  page to become one scrollable page (default 0). Requires webkitgtk >= 1.3.5.
-+* `enable_fullscreen`: If set to 1, Mozilla-style fullscreening will be
-+  available (default 0). Requires webkitgtk >= 1.3.8
-+* `enable_dns_prefetch`: If set to 1, domain names will be prefetched
-+  (default 1). Private browsing does *not* affect this value. Requires
-+  webkitgtk >= 1.3.13.
-+* `display_insecure_content`: If set to 1, non-HTTPS content will be displayed
-+  on HTTPS pages (default 1). Requires webkitgtk >= 1.11.13.
-+* `run_insecure_content`: If set to 1, non-HTTPS content will be allowed to run
-+  on HTTPS pages (default 1). Requires webkitgtk >= 1.11.13.
-+* `maintain_history`: If set to 1, the back/forward list will be kept. (default
-+  1).
-+* `enable_webgl`: If set to 1, WebGL support will be enabled (default 0).
-+  Requires webkitgtk >= 1.3.14.
-+* `local_storage_path`: Where to store local databases (default
-+  $XDG_DATA_HOME/webkit/databases/). Requires webkit >= 1.5.2.
-+* `enable_webaudio`: If set to 1, allows JavaScript to generate audio
-+  directly (default 0). Requires webkit >= 1.7.5.
-+* `enable_3d_acceleration`: If set to 1, the GPU will be used to render
-+  animations and 3D CSS transformations. Requires webkitgtk >= 1.7.90.
-+* `zoom_text_only`: If set to 1, only text will be zoomed (default 0). Requires
-+  webkit2gtk >= 1.7.91.
-+* `enable_smooth_scrolling`: If set to 1, scrolling the page will be smoothed
-+  (default 0). Requires webkitgtk >= 1.9.0.
-+* `enable_inline_media`: If set to 1, inline playback of media is allowed,
-+  otherwise, only full-screen playback is allowed (default 1). Requires
-+  webkitgtk >= 1.9.3.
-+* `require_click_to_play`: If set to 1, playback of media requires user
-+  interaction before playing, otherwise, media will be allowed to autoplay
-+  (default 0). Requires webkitgtk >= 1.9.3.
-+* `enable_css_shaders`: If set to 1, CSS shaders will be enabled (default 0).
-+  Requires webkitgtk >= 1.11.1.
-+* `enable_media_stream`: If set to 1, web pages will be able to access the
-+  local video and audio input devices (default 0). Requires webkitgtk >= 1.11.1.
-+* `cache_model`: The cache model of webkit. Valid values:
-+  "document_viewer" (no caching; low memory; usage: single local file),
-+  "web_browser" (heavy caching; faster; usage: general browsing),
-+  "document_browser" (moderate caching; usage: series of local files)
-+  (default "web_browser").
-+* `app_cache_size`: The maximum size of the application cache (in bytes)
-+  (default UINT_MAX (no quota)). Changing the variable clears the cache.
-+  Requires webkitgtk >= 1.3.13.
-+* `web_database_directory`: The directory where web databases are stored.
-+  (default is under $XDG_DATA_HOME).
-+* `web_database_quota`: The default quota for web databases. (default 5MB).
-+* `profile_js`: Sets whether to profile JavaScript code.
-+* `profile_timeline`: Sets whether to profile the timeline.
- 
- #### Constants (not dumpable or writeable)
- 
-@@ -396,6 +510,13 @@ file).
-   - overridable with cmdline arg
-   - in GtkSocket mode, this is a random number to prevent name clashes
- * `PID`: The process ID of this Uzbl instance.
-+* `current_encoding`: The current encoding of the web page.
-+* `inspected_uri`: The URI that is being inspected. Requires webkitgtk >=
-+  1.3.17.
-+* `app_cache_directory`: The directory webkit uses to store its cache.
-+  Requires webkitgtk >= 1.3.13.
-+* `plugin_list`: A JSON list of objects describing the available plugins.
-+  Requires webkitgtk >= 1.3.8.
- 
- ### VARIABLE EXPANSION AND COMMAND / JAVASCRIPT SUBSTITUTION
- 
-@@ -514,10 +635,10 @@ access to the following environment variables:
- * `$UZBL_SOCKET`: The filename of the Unix socket being used, if any.
- * `$UZBL_URI`: The URI of the current page.
- * `$UZBL_TITLE`: The current page title.
-+* `$UZBL_PRIVATE`: Set if uzbl is in "private browsing mode", unset otherwise.
- 
--Handler scripts (`download_handler`, `cookie_handler`, `scheme_handler`,
--`request_handler`, and `authentication_handler`) are called with special
--arguments:
-+Handler scripts (`download_handler`, `scheme_handler`, and `request_handler`)
-+are called with special arguments:
- 
- * download handler
- 
-@@ -532,16 +653,6 @@ arguments:
-     that the file should be saved to. A download handler using WebKit's internal
-     downloader can just echo this path and exit when this argument is present.
- 
--* cookie handler
--
--  - `$1 GET/PUT`: Whether a cookie should be sent to the server (`GET`) or
--    stored by the browser (`PUT`).
--  - `$2 scheme`: Either `http` or `https`.
--  - `$3 host`: If current page URL is `www.example.com/somepage`, this could be
--    something else than `example.com`, eg advertising from another host.
--  - `$4 path`: The request address path.
--  - `$5 data`: The cookie data. Only included for `PUT` requests.
--
- * scheme handler
- 
-   - `$1 URI` of the page to be navigated to
-@@ -550,13 +661,6 @@ arguments:
- 
-   - `$1 URI` of the resource which is being requested
- 
--* authentication handler:
--
--  - `$1`: authentication zone unique identifier
--  - `$2`: domain part of URL that requests authentication
--  - `$3`: authentication realm
--  - `$4`: FALSE if this is the first attempt to authenticate, TRUE otherwise
--
- ### Formfiller.sh
- 
- Example config entries for formfiller script
-@@ -584,47 +688,33 @@ after closing the editor, it will load the data into the formfields. The temp
- file is removed
- 
- ### HTTP/BASIC AUTHENTICATION
-+HTTP auth can be handled in two different ways. Using the builtin auth dialog
-+in WebKit or by dispatching the work to a external script.
- 
--You can use the authentication_handler variable to denote how http
--authentication should be handled.
--If this variable is:
--
--* not set or empty: use webkit internal auth dialog
--* a valid handler (i.e. {sh,sync}_spawn correct_script), use this handler
--* innvalid handler (spawn, some other command, uses script that does not
--  print anything): skip authentication.
--
--Example:
-+To use the builtin auth dialog set `enable_builtin_auth` to 1. With this set
-+you'll get a basic GTK+ prompt for username/password when trying to access a
-+protected site.
- 
--  set authentication_handler = sync_spawn /patch/to/your/script
-+Whenever authentication is needed the `AUTHENTICATE` event will be sent, this
-+is what you would use to hook up a custom authentication system. This event
-+will be sent even when using the bultin dialog so remember to disable that if
-+adding a dialog of your own.
- 
--Script will be executed on each authentication request.
--It will receive four auth-related parameters:
-+The `AUTHENTICATE` event has four arguments
-+ * a unique identifier to be used in the exchange
-+ * domain part of URL that requests authentication
-+ * authentication realm
-+ * the empty string for the first attempt and "retrying" for further attempts
- 
--    $1 authentication zone unique identifier (may be used as 'key')
--    $2 domain part of URL that requests authentication
--    $3 authentication realm
--    $4 FALSE if this is the first attempt to authenticate, TRUE otherwise
-+After this event has been sent the request is paused until credentials are
-+provided. This is done using the `auth` command e.g:
- 
--Script is expected to print exactly two lines of text on stdout (that means
--its output must contain exactly two '\n' bytes).
--The first line contains username, the second one - password.
--If authentication fails, script will be executed again (with $4 = TRUE).
--Non-interactive scripts should handle this case and do not try to
--authenticate again to avoid loops. If number of '\n' characters in scripts
--output does not equal 2, authentication will fail.
--That means 401 error will be displayed and uzbl won't try to authenticate anymore.
-+    `auth "uniqueid" "alice" "wonderland"`
- 
--The simplest example of authentication handler script is:
-+A super simple setup that will always try to authenticate with the same password
-+could look like this. (assuming aliases from the example configuration)
- 
--#!/bin/sh
--[ "$4" == "TRUE ] && exit
--echo alice
--echo wonderland
--
--This script tries to authenticate as user alice with password wonderland once
--and never retries authentication.
--See examples for more sofisticated, interactive authentication handler.
-+ at on_event AUTHENTICATE auth "%1" "alice" "wonderland"
- 
- ### WINDOW MANAGER INTEGRATION
- 
-@@ -657,11 +747,6 @@ The EM allows:
- * Many fine-grained events (`hover_over_link`, `key_press`, `key_release`,..)
- * See example `uzbl-event-manager`.
- 
--**Note**: Cookie events are sent in addition to (optionally) being handled by
--  the cookie handler (set by the cookie_handler var). If using a handler it will
--  take precedence before the internal state configured by (add|delete)_cookie
--  commands.
--
- Events have this format:
- 
-      EVENT [uzbl_instance_name] EVENT_NAME event_details
-@@ -687,14 +772,18 @@ Events have this format:
-   loaded. `uri` is the URI of the page being loaded.
- * `EVENT [uzbl_instance_name] LOAD_START uri`: A change of the page has been
-   requested. `uri` is the current URI; the one being departed.
--* `EVENT [uzbl_instance_name] LOAD_FINISHED uri`: Loading has finished for the
-+* `EVENT [uzbl_instance_name] LOAD_FINISH uri`: Loading has finished for the
-   page at `uri`.
- * `EVENT [uzbl_instance_name] LOAD_ERROR uri reason_of_error`: The URI `uri`
-   could not be loaded for the reason described in `reason_of_error`.
- * `EVENT [uzbl_instance_name] LOAD_PROGRESS percentage` : While the page is
-   loading, gives the `percentage` of the page that has finished loading.
-+* `EVENT [uzbl_instance_name] REQUEST_QUEUED uri`: http resource gets
-+  enqueued
- * `EVENT [uzbl_instance_name] REQUEST_STARTING uri`: http resource gets
-   requested
-+* `EVENT [uzbl_instance_name] REQUEST_FINISHED uri`: http resource has finished
-+  loading
- * `EVENT [uzbl_instance_name] TITLE_CHANGED title_name`: When the title of the
-   page (and hence maybe, the window title) changed. `title_name` is the new
-   title.
-@@ -743,6 +832,8 @@ Events have this format:
-   be a unix-timestamp or empty
- * `EVENT [uzbl_instance_name] DELETE_COOKIE domain path name value scheme expire`:
-   When a cookie was deleted. arguments as ADD_COOKIE
-+* `EVENT [uzbl_instance_name] AUTHENTICATE uniqueid host realm retry`: When a
-+  request requires authentication. authentication is done by calling `auth`
- 
- Events/requests which the EM and its plugins listens for
- 
-diff --git a/bin/uzbl-browser b/bin/uzbl-browser
-index fb9a368..4381050 100755
---- a/bin/uzbl-browser
-+++ b/bin/uzbl-browser
-@@ -67,9 +67,9 @@ fi
- # uzbl-event-manager will exit if one is already running.
- # we could also check if its pid file exists to avoid having to spawn it.
- DAEMON_SOCKET="$XDG_CACHE_HOME"/uzbl/event_daemon
--#if [ ! -f "$DAEMON_SOCKET".pid ]
--#then
-+if [ ! -f "$DAEMON_SOCKET".pid ]
-+then
- 	${UZBL_EVENT_MANAGER:-uzbl-event-manager -va start}
--#fi
-+fi
- 
- exec uzbl-core "$@" ${config_file:+--config "$config_file"} --connect-socket $DAEMON_SOCKET
-diff --git a/bin/uzbl-event-manager b/bin/uzbl-event-manager
-index 56253ef..221fa73 100755
---- a/bin/uzbl-event-manager
-+++ b/bin/uzbl-event-manager
-@@ -1,1011 +1,3 @@
--#!/usr/bin/env python2
--
--# Event Manager for Uzbl
--# Copyright (c) 2009-2010, Mason Larobina <mason.larobina at gmail.com>
--# Copyright (c) 2009, Dieter Plaetinck <dieter at plaetinck.be>
--#
--# This program 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.
--#
--# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
--
--'''
--
--E V E N T _ M A N A G E R . P Y
--===============================
--
--Event manager for uzbl written in python.
--
--'''
--
--import atexit
--import imp
--import logging
--import os
--import sys
--import time
--import weakref
--import re
--import errno
--from collections import defaultdict
--from functools import partial
--from glob import glob
--from itertools import count
--from optparse import OptionParser
--from select import select
--from signal import signal, SIGTERM, SIGINT, SIGKILL
--from socket import socket, AF_UNIX, SOCK_STREAM, error as socket_error
--from traceback import format_exc
--
--
--def xdghome(key, default):
--    '''Attempts to use the environ XDG_*_HOME paths if they exist otherwise
--    use $HOME and the default path.'''
--
--    xdgkey = "XDG_%s_HOME" % key
--    if xdgkey in os.environ.keys() and os.environ[xdgkey]:
--        return os.environ[xdgkey]
--
--    return os.path.join(os.environ['HOME'], default)
--
--# `make install` will put the correct value here for your system
--PREFIX = '/usr/local/'
--
--# Setup xdg paths.
--DATA_DIR = os.path.join(xdghome('DATA', '.local/share/'), 'uzbl/')
--CACHE_DIR = os.path.join(xdghome('CACHE', '.cache/'), 'uzbl/')
--
--# Define some globals.
--SCRIPTNAME = os.path.basename(sys.argv[0])
--
--logger = logging.getLogger(SCRIPTNAME)
--
--
--def get_exc():
--    '''Format `format_exc` for logging.'''
--    return "\n%s" % format_exc().rstrip()
--
--
--def expandpath(path):
--    '''Expand and realpath paths.'''
--    return os.path.realpath(os.path.expandvars(path))
--
--
--def ascii(u):
--    '''Convert unicode strings into ascii for transmission over
--    ascii-only streams/sockets/devices.'''
--    return u.encode('utf-8')
--
--
--def daemonize():
--    '''Daemonize the process using the Stevens' double-fork magic.'''
--
--    logger.info('entering daemon mode')
--
--    try:
--        if os.fork():
--            os._exit(0)
--
--    except OSError:
--        logger.critical('failed to daemonize', exc_info=True)
--        sys.exit(1)
--
--    os.chdir('/')
--    os.setsid()
--    os.umask(0)
--
--    try:
--        if os.fork():
--            os._exit(0)
--
--    except OSError:
--        logger.critical('failed to daemonize', exc_info=True)
--        sys.exit(1)
--
--    if sys.stdout.isatty():
--        sys.stdout.flush()
--        sys.stderr.flush()
--
--    devnull = '/dev/null'
--    stdin = file(devnull, 'r')
--    stdout = file(devnull, 'a+')
--    stderr = file(devnull, 'a+', 0)
--
--    os.dup2(stdin.fileno(), sys.stdin.fileno())
--    os.dup2(stdout.fileno(), sys.stdout.fileno())
--    os.dup2(stderr.fileno(), sys.stderr.fileno())
--
--    logger.info('entered daemon mode')
--
--
--def make_dirs(path):
--    '''Make all basedirs recursively as required.'''
--
--    try:
--        dirname = os.path.dirname(path)
--        if not os.path.isdir(dirname):
--            logger.debug('creating directories %r', dirname)
--            os.makedirs(dirname)
--
--    except OSError:
--        logger.error('failed to create directories', exc_info=True)
--
--
--class EventHandler(object):
--    '''Event handler class. Used to store args and kwargs which are merged
--    come time to call the callback with the event args and kwargs.'''
--
--    nextid = count().next
--
--    def __init__(self, plugin, event, callback, args, kwargs):
--        self.id = self.nextid()
--        self.plugin = plugin
--        self.event = event
--        self.callback = callback
--        self.args = args
--        self.kwargs = kwargs
--
--    def __repr__(self):
--        elems = ['id=%d' % self.id, 'event=%s' % self.event,
--            'callback=%r' % self.callback]
--
--        if self.args:
--            elems.append('args=%s' % repr(self.args))
--
--        if self.kwargs:
--            elems.append('kwargs=%s' % repr(self.kwargs))
--
--        elems.append('plugin=%s' % self.plugin.name)
--        return u'<handler(%s)>' % ', '.join(elems)
--
--    def call(self, uzbl, *args, **kwargs):
--        '''Execute the handler function and merge argument lists.'''
--
--        args = args + self.args
--        kwargs = dict(self.kwargs.items() + kwargs.items())
--        self.callback(uzbl, *args, **kwargs)
--
--
--class Plugin(object):
--    '''Plugin module wrapper object.'''
--
--    # Special functions exported from the Plugin instance to the
--    # plugin namespace.
--    special_functions = ['require', 'export', 'export_dict', 'connect',
--            'connect_dict', 'logger', 'unquote', 'splitquoted']
--
--    def __init__(self, parent, name, path, plugin):
--        self.parent = parent
--        self.name = name
--        self.path = path
--        self.plugin = plugin
--        self.logger = logging.getLogger('plugin.%s' % name)
--
--        # Weakrefs to all handlers created by this plugin
--        self.handlers = set([])
--
--        # Plugins init hook
--        init = getattr(plugin, 'init', None)
--        self.init = init if callable(init) else None
--
--        # Plugins optional after hook
--        after = getattr(plugin, 'after', None)
--        self.after = after if callable(after) else None
--
--        # Plugins optional cleanup hook
--        cleanup = getattr(plugin, 'cleanup', None)
--        self.cleanup = cleanup if callable(cleanup) else None
--
--        assert init or after or cleanup, "missing hooks in plugin"
--
--        # Export plugin's instance methods to plugin namespace
--        for attr in self.special_functions:
--            plugin.__dict__[attr] = getattr(self, attr)
--
--    def __repr__(self):
--        return u'<plugin(%r)>' % self.plugin
--
--    def export(self, uzbl, attr, obj, prepend=True):
--        '''Attach `obj` to `uzbl` instance. This is the preferred method
--        of sharing functionality, functions, data and objects between
--        plugins.
--
--        If the object is callable you may wish to turn the callable object
--        in to a meta-instance-method by prepending `uzbl` to the call stack.
--        You can change this behaviour with the `prepend` argument.
--        '''
--
--        assert attr not in uzbl.exports, "attr %r already exported by %r" %\
--            (attr, uzbl.exports[attr][0])
--
--        prepend = True if prepend and callable(obj) else False
--        uzbl.__dict__[attr] = partial(obj, uzbl) if prepend else obj
--        uzbl.exports[attr] = (self, obj, prepend)
--        uzbl.logger.info('exported %r to %r by plugin %r, prepended %r',
--            obj, 'uzbl.%s' % attr, self.name, prepend)
--
--    def export_dict(self, uzbl, exports):
--        for (attr, object) in exports.items():
--            self.export(uzbl, attr, object)
--
--    def find_handler(self, event, callback, args, kwargs):
--        '''Check if a handler with the identical callback and arguments
--        exists and return it.'''
--
--        # Remove dead refs
--        self.handlers -= set(filter(lambda ref: not ref(), self.handlers))
--
--        # Find existing identical handler
--        for handler in [ref() for ref in self.handlers]:
--            if handler.event == event and handler.callback == callback \
--              and handler.args == args and handler.kwargs == kwargs:
--                return handler
--
--    def connect(self, uzbl, event, callback, *args, **kwargs):
--        '''Create an event handler object which handles `event` events.
--
--        Arguments passed to the connect function (`args` and `kwargs`) are
--        stored in the handler object and merged with the event arguments
--        come handler execution.
--
--        All handler functions must behave like a `uzbl` instance-method (that
--        means `uzbl` is prepended to the callback call arguments).'''
--
--        # Sanitise and check event name
--        event = event.upper().strip()
--        assert event and ' ' not in event
--
--        assert callable(callback), 'callback must be callable'
--
--        # Check if an identical handler already exists
--        handler = self.find_handler(event, callback, args, kwargs)
--        if not handler:
--            # Create a new handler
--            handler = EventHandler(self, event, callback, args, kwargs)
--            self.handlers.add(weakref.ref(handler))
--            self.logger.info('new %r', handler)
--
--        uzbl.handlers[event].append(handler)
--        uzbl.logger.info('connected %r', handler)
--        return handler
--
--    def connect_dict(self, uzbl, connects):
--        for (event, callback) in connects.items():
--            self.connect(uzbl, event, callback)
--
--    def require(self, plugin):
--        '''Check that plugin with name `plugin` has been loaded. Use this to
--        ensure that your plugins dependencies have been met.'''
--
--        assert plugin in self.parent.plugins, self.logger.critical(
--            'plugin %r required by plugin %r', plugin, self.name)
--
--    @classmethod
--    def unquote(cls, s):
--        '''Removes quotation marks around strings if any and interprets
--        \\-escape sequences using `string_escape`'''
--        if s and s[0] == s[-1] and s[0] in ['"', "'"]:
--            s = s[1:-1]
--        return s.encode('utf-8').decode('string_escape').decode('utf-8')
--
--    _splitquoted = re.compile("( |\"(?:\\\\.|[^\"])*?\"|'(?:\\\\.|[^'])*?')")
--
--    @classmethod
--    def splitquoted(cls, text):
--        '''Splits string on whitespace while respecting quotations'''
--        parts = cls._splitquoted.split(text)
--        return [cls.unquote(p) for p in parts if p.strip()]
--
--
--class Uzbl(object):
--    def __init__(self, parent, child_socket):
--        self.opts = opts
--        self.parent = parent
--        self.child_socket = child_socket
--        self.child_buffer = []
--        self.time = time.time()
--        self.pid = None
--        self.name = None
--
--        # Flag if the instance has raised the INSTANCE_START event.
--        self.instance_start = False
--
--        # Use name "unknown" until name is discovered.
--        self.logger = logging.getLogger('uzbl-instance[]')
--
--        # Track plugin event handlers and exported functions.
--        self.exports = {}
--        self.handlers = defaultdict(list)
--
--        # Internal vars
--        self._depth = 0
--        self._buffer = ''
--
--    def __repr__(self):
--        return '<uzbl(%s)>' % ', '.join([
--            'pid=%s' % (self.pid if self.pid else "Unknown"),
--            'name=%s' % ('%r' % self.name if self.name else "Unknown"),
--            'uptime=%f' % (time.time() - self.time),
--            '%d exports' % len(self.exports.keys()),
--            '%d handlers' % sum([len(l) for l in self.handlers.values()])])
--
--    def init_plugins(self):
--        '''Call the init and after hooks in all loaded plugins for this
--        instance.'''
--
--        # Initialise each plugin with the current uzbl instance.
--        for plugin in self.parent.plugins.values():
--            if plugin.init:
--                self.logger.debug('calling %r plugin init hook', plugin.name)
--                plugin.init(self)
--
--        # Allow plugins to use exported features of other plugins by calling an
--        # optional `after` function in the plugins namespace.
--        for plugin in self.parent.plugins.values():
--            if plugin.after:
--                self.logger.debug('calling %r plugin after hook', plugin.name)
--                plugin.after(self)
--
--    def send(self, msg):
--        '''Send a command to the uzbl instance via the child socket
--        instance.'''
--
--        msg = msg.strip()
--        assert self.child_socket, "socket inactive"
--
--        if opts.print_events:
--            print ascii(u'%s<-- %s' % ('  ' * self._depth, msg))
--
--        self.child_buffer.append(ascii("%s\n" % msg))
--
--    def do_send(self):
--        data = ''.join(self.child_buffer)
--        try:
--            bsent = self.child_socket.send(data)
--        except socket_error as e:
--            if e.errno in (errno.EAGAIN, errno.EINTR):
--                self.child_buffer = [data]
--                return
--            else:
--                self.logger.error('failed to send', exc_info=True)
--                return self.close()
--        else:
--            if bsent == 0:
--                self.logger.debug('write end of connection closed')
--                self.close()
--            elif bsent < len(data):
--                self.child_buffer = [data[bsent:]]
--            else:
--                del self.child_buffer[:]
--
--    def read(self):
--        '''Read data from the child socket and pass lines to the parse_msg
--        function.'''
--
--        try:
--            raw = unicode(self.child_socket.recv(8192), 'utf-8', 'ignore')
--            if not raw:
--                self.logger.debug('read null byte')
--                return self.close()
--
--        except:
--            self.logger.error('failed to read', exc_info=True)
--            return self.close()
--
--        lines = (self._buffer + raw).split('\n')
--        self._buffer = lines.pop()
--
--        for line in filter(None, map(unicode.strip, lines)):
--            try:
--                self.parse_msg(line.strip())
--
--            except:
--                self.logger.error(get_exc())
--                self.logger.error('erroneous event: %r' % line)
--
--    def parse_msg(self, line):
--        '''Parse an incoming message from a uzbl instance. Event strings
--        will be parsed into `self.event(event, args)`.'''
--
--        # Split by spaces (and fill missing with nulls)
--        elems = (line.split(' ', 3) + [''] * 3)[:4]
--
--        # Ignore non-event messages.
--        if elems[0] != 'EVENT':
--            logger.info('non-event message: %r', line)
--            if opts.print_events:
--                print '--- %s' % ascii(line)
--            return
--
--        # Check event string elements
--        (name, event, args) = elems[1:]
--        assert name and event, 'event string missing elements'
--        if not self.name:
--            self.name = name
--            self.logger = logging.getLogger('uzbl-instance%s' % name)
--            self.logger.info('found instance name %r', name)
--
--        assert self.name == name, 'instance name mismatch'
--
--        # Handle the event with the event handlers through the event method
--        self.event(event, args)
--
--    def event(self, event, *args, **kargs):
--        '''Raise an event.'''
--
--        event = event.upper()
--
--        if not opts.daemon_mode and opts.print_events:
--            elems = [event]
--            if args:
--                elems.append(unicode(args))
--            if kargs:
--                elems.append(unicode(kargs))
--            print ascii(u'%s--> %s' % ('  ' * self._depth, ' '.join(elems)))
--
--        if event == "INSTANCE_START" and args:
--            assert not self.instance_start, 'instance already started'
--
--            self.pid = int(args[0])
--            self.logger.info('found instance pid %r', self.pid)
--
--            self.init_plugins()
--
--        elif event == "INSTANCE_EXIT":
--            self.logger.info('uzbl instance exit')
--            self.close()
--
--        if event not in self.handlers:
--            return
--
--        for handler in self.handlers[event]:
--            self._depth += 1
--            try:
--                handler.call(self, *args, **kargs)
--
--            except:
--                self.logger.error('error in handler', exc_info=True)
--
--            self._depth -= 1
--
--    def close_connection(self, child_socket):
--        '''Close child socket and delete the uzbl instance created for that
--        child socket connection.'''
--
--    def close(self):
--        '''Close the client socket and call the plugin cleanup hooks.'''
--
--        self.logger.debug('called close method')
--
--        # Remove self from parent uzbls dict.
--        if self.child_socket in self.parent.uzbls:
--            self.logger.debug('removing self from uzbls list')
--            del self.parent.uzbls[self.child_socket]
--
--        try:
--            if self.child_socket:
--                self.logger.debug('closing child socket')
--                self.child_socket.close()
--
--        except:
--            self.logger.error('failed to close socket', exc_info=True)
--
--        finally:
--            self.child_socket = None
--
--        # Call plugins cleanup hooks.
--        for plugin in self.parent.plugins.values():
--            if plugin.cleanup:
--                self.logger.debug('calling %r plugin cleanup hook',
--                    plugin.name)
--                plugin.cleanup(self)
--
--        logger.info('removed %r', self)
--
--
--class UzblEventDaemon(object):
--    def __init__(self):
--        self.opts = opts
--        self.server_socket = None
--        self._quit = False
--
--        # Hold uzbl instances
--        # {child socket: Uzbl instance, ..}
--        self.uzbls = {}
--
--        # Hold plugins
--        # {plugin name: Plugin instance, ..}
--        self.plugins = {}
--
--        # Register that the event daemon server has started by creating the
--        # pid file.
--        make_pid_file(opts.pid_file)
--
--        # Register a function to clean up the socket and pid file on exit.
--        atexit.register(self.quit)
--
--        # Add signal handlers.
--        for sigint in [SIGTERM, SIGINT]:
--            signal(sigint, self.quit)
--
--        # Load plugins into self.plugins
--        self.load_plugins(opts.plugins)
--
--    def load_plugins(self, plugins):
--        '''Load event manager plugins.'''
--
--        for path in plugins:
--            logger.debug('loading plugin %r', path)
--            (dir, file) = os.path.split(path)
--            name = file[:-3] if file.lower().endswith('.py') else file
--
--            info = imp.find_module(name, [dir])
--            module = imp.load_module(name, *info)
--
--            # Check if the plugin has a callable hook.
--            hooks = filter(callable, [getattr(module, attr, None) \
--                for attr in ['init', 'after', 'cleanup']])
--            assert hooks, "no hooks in plugin %r" % module
--
--            logger.debug('creating plugin instance for %r plugin', name)
--            plugin = Plugin(self, name, path, module)
--            self.plugins[name] = plugin
--            logger.info('new %r', plugin)
--
--    def create_server_socket(self):
--        '''Create the event manager daemon socket for uzbl instance duplex
--        communication.'''
--
--        # Close old socket.
--        self.close_server_socket()
--
--        sock = socket(AF_UNIX, SOCK_STREAM)
--        sock.bind(opts.server_socket)
--        sock.listen(5)
--
--        self.server_socket = sock
--        logger.debug('bound server socket to %r', opts.server_socket)
--
--    def run(self):
--        '''Main event daemon loop.'''
--
--        logger.debug('entering main loop')
--
--        # Create and listen on the server socket
--        self.create_server_socket()
--
--        if opts.daemon_mode:
--            # Daemonize the process
--            daemonize()
--
--            # Update the pid file
--            make_pid_file(opts.pid_file)
--
--        try:
--            # Accept incoming connections and listen for incoming data
--            self.listen()
--
--        except:
--            if not self._quit:
--                logger.critical('failed to listen', exc_info=True)
--
--        # Clean up and exit
--        self.quit()
--
--        logger.debug('exiting main loop')
--
--    def listen(self):
--        '''Accept incoming connections and constantly poll instance sockets
--        for incoming data.'''
--
--        logger.info('listening on %r', opts.server_socket)
--
--        # Count accepted connections
--        connections = 0
--
--        while (self.uzbls or not connections) or (not opts.auto_close):
--            socks = [self.server_socket] + self.uzbls.keys()
--            wsocks = [k for k, v in self.uzbls.items() if v.child_buffer]
--            reads, writes, errors = select(socks, wsocks, socks, 1)
--
--            if self.server_socket in reads:
--                reads.remove(self.server_socket)
--
--                # Accept connection and create uzbl instance.
--                child_socket = self.server_socket.accept()[0]
--                child_socket.setblocking(False)
--                self.uzbls[child_socket] = Uzbl(self, child_socket)
--                connections += 1
--
--            for uzbl in [self.uzbls[s] for s in writes if s in self.uzbls ]:
--                uzbl.do_send()
--
--            for uzbl in [self.uzbls[s] for s in reads if s in self.uzbls]:
--                uzbl.read()
--
--            for uzbl in [self.uzbls[s] for s in errors if s in self.uzbls]:
--                uzbl.logger.error('socket read error')
--                uzbl.close()
--
--        logger.info('auto closing')
--
--    def close_server_socket(self):
--        '''Close and delete the server socket.'''
--
--        try:
--            if self.server_socket:
--                logger.debug('closing server socket')
--                self.server_socket.close()
--                self.server_socket = None
--
--            if os.path.exists(opts.server_socket):
--                logger.info('unlinking %r', opts.server_socket)
--                os.unlink(opts.server_socket)
--
--        except:
--            logger.error('failed to close server socket', exc_info=True)
--
--    def quit(self, sigint=None, *args):
--        '''Close all instance socket objects, server socket and delete the
--        pid file.'''
--
--        if sigint == SIGTERM:
--            logger.critical('caught SIGTERM, exiting')
--
--        elif sigint == SIGINT:
--            logger.critical('caught SIGINT, exiting')
--
--        elif not self._quit:
--            logger.debug('shutting down event manager')
--
--        self.close_server_socket()
--
--        for uzbl in self.uzbls.values():
--            uzbl.close()
--
--        del_pid_file(opts.pid_file)
--
--        if not self._quit:
--            logger.info('event manager shut down')
--            self._quit = True
--
--
--def make_pid_file(pid_file):
--    '''Creates a pid file at `pid_file`, fails silently.'''
--
--    try:
--        logger.debug('creating pid file %r', pid_file)
--        make_dirs(pid_file)
--        pid = os.getpid()
--        fileobj = open(pid_file, 'w')
--        fileobj.write('%d' % pid)
--        fileobj.close()
--        logger.info('created pid file %r with pid %d', pid_file, pid)
--
--    except:
--        logger.error('failed to create pid file', exc_info=True)
--
--
--def del_pid_file(pid_file):
--    '''Deletes a pid file at `pid_file`, fails silently.'''
--
--    if os.path.isfile(pid_file):
--        try:
--            logger.debug('deleting pid file %r', pid_file)
--            os.remove(pid_file)
--            logger.info('deleted pid file %r', pid_file)
--
--        except:
--            logger.error('failed to delete pid file', exc_info=True)
--
--
--def get_pid(pid_file):
--    '''Reads a pid from pid file `pid_file`, fails None.'''
--
--    try:
--        logger.debug('reading pid file %r', pid_file)
--        fileobj = open(pid_file, 'r')
--        pid = int(fileobj.read())
--        fileobj.close()
--        logger.info('read pid %d from pid file %r', pid, pid_file)
--        return pid
--
--    except (IOError, ValueError):
--        logger.error('failed to read pid', exc_info=True)
--        return None
--
--
--def pid_running(pid):
--    '''Checks if a process with a pid `pid` is running.'''
--
--    try:
--        os.kill(pid, 0)
--    except OSError:
--        return False
--    else:
--        return True
--
--
--def term_process(pid):
--    '''Asks nicely then forces process with pid `pid` to exit.'''
--
--    try:
--        logger.info('sending SIGTERM to process with pid %r', pid)
--        os.kill(pid, SIGTERM)
--
--    except OSError:
--        logger.error(get_exc())
--
--    logger.debug('waiting for process with pid %r to exit', pid)
--    start = time.time()
--    while True:
--        if not pid_running(pid):
--            logger.debug('process with pid %d exit', pid)
--            return True
--
--        if (time.time() - start) > 5:
--            logger.warning('process with pid %d failed to exit', pid)
--            logger.info('sending SIGKILL to process with pid %d', pid)
--            try:
--                os.kill(pid, SIGKILL)
--            except:
--                logger.critical('failed to kill %d', pid, exc_info=True)
--                raise
--
--        if (time.time() - start) > 10:
--            logger.critical('unable to kill process with pid %d', pid)
--            raise OSError
--
--        time.sleep(0.25)
--
--
--def stop_action():
--    '''Stop the event manager daemon.'''
--
--    pid_file = opts.pid_file
--    if not os.path.isfile(pid_file):
--        logger.error('could not find running event manager with pid file %r',
--            pid_file)
--        return
--
--    pid = get_pid(pid_file)
--    if not pid_running(pid):
--        logger.debug('no process with pid %r', pid)
--        del_pid_file(pid_file)
--        return
--
--    logger.debug('terminating process with pid %r', pid)
--    term_process(pid)
--    del_pid_file(pid_file)
--    logger.info('stopped event manager process with pid %d', pid)
--
--
--def start_action():
--    '''Start the event manager daemon.'''
--
--    pid_file = opts.pid_file
--    if os.path.isfile(pid_file):
--        pid = get_pid(pid_file)
--        if pid_running(pid):
--            logger.error('event manager already started with pid %d', pid)
--            return
--
--        logger.info('no process with pid %d', pid)
--        del_pid_file(pid_file)
--
--    UzblEventDaemon().run()
--
--
--def restart_action():
--    '''Restart the event manager daemon.'''
--
--    stop_action()
--    start_action()
--
--
--def list_action():
--    '''List all the plugins that would be loaded in the current search
--    dirs.'''
--
--    names = {}
--    for plugin in opts.plugins:
--        (head, tail) = os.path.split(plugin)
--        if tail not in names:
--            names[tail] = plugin
--
--    for plugin in sorted(names.values()):
--        print plugin
--
--
--def make_parser():
--    parser = OptionParser('usage: %prog [options] {start|stop|restart|list}')
--    add = parser.add_option
--
--    add('-v', '--verbose',
--        dest='verbose', default=2, action='count',
--        help='increase verbosity')
--
--    add('-d', '--plugin-dir',
--        dest='plugin_dirs', action='append', metavar="DIR", default=[],
--        help='add extra plugin search dir, same as `-l "DIR/*.py"`')
--
--    add('-l', '--load-plugin',
--        dest='load_plugins', action='append', metavar="PLUGIN", default=[],
--        help='load plugin, loads before plugins in search dirs')
--
--    socket_location = os.path.join(CACHE_DIR, 'event_daemon')
--
--    add('-s', '--server-socket',
--        dest='server_socket', metavar="SOCKET", default=socket_location,
--        help='server AF_UNIX socket location')
--
--    add('-p', '--pid-file',
--        metavar="FILE", dest='pid_file',
--        help='pid file location, defaults to server socket + .pid')
--
--    add('-n', '--no-daemon',
--        dest='daemon_mode', action='store_false', default=True,
--        help='do not daemonize the process')
--
--    add('-a', '--auto-close',
--        dest='auto_close', action='store_true', default=False,
--        help='auto close after all instances disconnect')
--
--    add('-i', '--no-default-dirs',
--        dest='default_dirs', action='store_false', default=True,
--        help='ignore the default plugin search dirs')
--
--    add('-o', '--log-file',
--        dest='log_file', metavar='FILE',
--        help='write logging output to a file, defaults to server socket +'
--        ' .log')
--
--    add('-q', '--quiet-events',
--        dest='print_events', action="store_false", default=True,
--        help="silence the printing of events to stdout")
--
--    return parser
--
--
--def init_logger():
--    log_level = logging.CRITICAL - opts.verbose * 10
--    logger = logging.getLogger()
--    logger.setLevel(max(log_level, 10))
--
--    # Console
--    handler = logging.StreamHandler()
--    handler.setLevel(max(log_level + 10, 10))
--    handler.setFormatter(logging.Formatter(
--        '%(name)s: %(levelname)s: %(message)s'))
--    logger.addHandler(handler)
--
--    # Logfile
--    handler = logging.FileHandler(opts.log_file, 'w', 'utf-8', 1)
--    handler.setLevel(max(log_level, 10))
--    handler.setFormatter(logging.Formatter(
--        '[%(created)f] %(name)s: %(levelname)s: %(message)s'))
--    logger.addHandler(handler)
--
--
--def main():
--    global opts
--
--    parser = make_parser()
--
--    (opts, args) = parser.parse_args()
--
--    opts.server_socket = expandpath(opts.server_socket)
--
--    # Set default pid file location
--    if not opts.pid_file:
--        opts.pid_file = "%s.pid" % opts.server_socket
--
--    else:
--        opts.pid_file = expandpath(opts.pid_file)
--
--    # Set default log file location
--    if not opts.log_file:
--        opts.log_file = "%s.log" % opts.server_socket
--
--    else:
--        opts.log_file = expandpath(opts.log_file)
--
--    # Logging setup
--    init_logger()
--    logger.info('logging to %r', opts.log_file)
--
--    plugins = {}
--
--    # Load all `opts.load_plugins` into the plugins list
--    for path in opts.load_plugins:
--        path = expandpath(path)
--        matches = glob(path)
--        if not matches:
--            parser.error('cannot find plugin(s): %r' % path)
--
--        for plugin in matches:
--            (head, tail) = os.path.split(plugin)
--            if tail not in plugins:
--                logger.debug('found plugin: %r', plugin)
--                plugins[tail] = plugin
--
--            else:
--                logger.debug('ignoring plugin: %r', plugin)
--
--    # Add default plugin locations
--    if opts.default_dirs:
--        logger.debug('adding default plugin dirs to plugin dirs list')
--        opts.plugin_dirs += [os.path.join(DATA_DIR, 'plugins/'),
--            os.path.join(PREFIX, 'share/uzbl/examples/data/plugins/')]
--
--    else:
--        logger.debug('ignoring default plugin dirs')
--
--    # Load all plugins in `opts.plugin_dirs` into the plugins list
--    for dir in opts.plugin_dirs:
--        dir = expandpath(dir)
--        logger.debug('searching plugin dir: %r', dir)
--        for plugin in glob(os.path.join(dir, '*.py')):
--            (head, tail) = os.path.split(plugin)
--            if tail not in plugins:
--                logger.debug('found plugin: %r', plugin)
--                plugins[tail] = plugin
--
--            else:
--                logger.debug('ignoring plugin: %r', plugin)
--
--    plugins = plugins.values()
--
--    # Check all the paths in the plugins list are files
--    for plugin in plugins:
--        if not os.path.isfile(plugin):
--            parser.error('plugin not a file: %r' % plugin)
--
--    if opts.auto_close:
--        logger.debug('will auto close')
--    else:
--        logger.debug('will not auto close')
--
--    if opts.daemon_mode:
--        logger.debug('will daemonize')
--    else:
--        logger.debug('will not daemonize')
--
--    opts.plugins = plugins
--
--    # init like {start|stop|..} daemon actions
--    daemon_actions = {'start': start_action, 'stop': stop_action,
--        'restart': restart_action, 'list': list_action}
--
--    if len(args) == 1:
--        action = args[0]
--        if action not in daemon_actions:
--            parser.error('invalid action: %r' % action)
--
--    elif not args:
--        action = 'start'
--        logger.warning('no daemon action given, assuming %r', action)
--
--    else:
--        parser.error('invalid action argument: %r' % args)
--
--    logger.info('daemon action %r', action)
--    # Do action
--    daemon_actions[action]()
--
--    logger.debug('process CPU time: %f', time.clock())
--
--
--if __name__ == "__main__":
--    main()
--
--
--# vi: set et ts=4:
-+#!/usr/bin/python3
-+from uzbl import event_manager
-+event_manager.main()
-diff --git a/bin/uzbl-tabbed b/bin/uzbl-tabbed
-index b78a54a..12fa249 100755
---- a/bin/uzbl-tabbed
-+++ b/bin/uzbl-tabbed
-@@ -47,6 +47,10 @@
- #
- #   Simon Lipp (sloonz)
- #       Various
-+#
-+#   Hakan Jerning
-+#       Wrote autosave_session patch to have a saved session even if
-+#       uzbl-tabbed is closed unexpectedly.
- 
- 
- # Dependencies:
-@@ -85,6 +89,7 @@
- #   save_session            = 1
- #   json_session            = 0
- #   session_file            = $HOME/.local/share/uzbl/session
-+#   autosave_session        = 0
- #
- # Inherited uzbl options:
- #   icon_path               = $HOME/.local/share/uzbl/uzbl.png
-@@ -209,6 +214,7 @@ config = {
-   'save_session':           True,   # Save session in file when quit
-   'saved_sessions_dir':     os.path.join(DATA_DIR, 'sessions/'),
-   'session_file':           os.path.join(DATA_DIR, 'session'),
-+  'autosave_session':       False,  # Save session for every tab change
- 
-   # Inherited uzbl options
-   'icon_path':              os.path.join(DATA_DIR, 'uzbl.png'),
-@@ -232,6 +238,11 @@ config = {
-   'selected_https':         'foreground = "#fff"',
-   'selected_https_text':    'foreground = "gold"',
- 
-+  #Explicit config file. Unlike the other configs, this one cannot be inherited
-+  #from the uzbl config file, as stated above. I've only put it here because
-+  #load_session() is already called in UzblTabbed.__init__.
-+  'explicit_config_file':   None,
-+
- } # End of config dict.
- 
- UZBL_TABBED_VARS = config.keys()
-@@ -410,7 +421,7 @@ class GlobalEventDispatcher(EventDispatcher):
-     def new_tab(self, uri = ''):
-         self.uzbl_tabbed.new_tab(uri)
- 
--    def new_tab_bg(self, uri = ''):
-+    def new_bg_tab(self, uri = ''):
-         self.uzbl_tabbed.new_tab(uri, switch = False)
- 
-     def new_tab_next(self, uri = ''):
-@@ -434,6 +445,15 @@ class GlobalEventDispatcher(EventDispatcher):
-     def last_tab(self):
-         self.uzbl_tabbed.goto_tab(-1)
- 
-+    def move_current_tab(self, index=0):
-+        self.uzbl_tabbed.move_current_tab(absolute=int(index))
-+
-+    def move_current_tab_left(self):
-+        self.uzbl_tabbed.move_current_tab(relative=-1)
-+
-+    def move_current_tab_right(self):
-+        self.uzbl_tabbed.move_current_tab(relative=1)
-+
-     def preset_tabs(self, *args):
-         self.uzbl_tabbed.run_preset_command(*args)
- 
-@@ -889,6 +909,9 @@ class UzblTabbed:
-         if(uri):
-           cmd = cmd + ['--uri', str(uri)]
- 
-+        if config['explicit_config_file'] is not None:
-+            cmd = cmd + ['-c', config['explicit_config_file']]
-+
-         gobject.spawn_async(cmd, flags=gobject.SPAWN_SEARCH_PATH)
- 
-         uzbl = UzblInstance(self, name, uri, title, switch)
-@@ -968,6 +991,18 @@ class UzblTabbed:
-         while tabn < 0: tabn += ntabs
-         self.goto_tab(tabn)
- 
-+    def move_tab(self, tab, index):
-+        '''Move tab to position.'''
-+        self.notebook.reorder_child(tab, index)
-+        self.update_tablist()
-+
-+    def move_current_tab(self, absolute=None, relative=None):
-+        '''Move current tab to position.'''
-+        current = self.notebook.get_current_page()
-+        index = absolute if absolute is not None else current + relative \
-+                if current + relative < len(self.notebook) else 0
-+        tab = self.notebook.get_nth_page(current)
-+        self.move_tab(tab, index)
- 
-     def close_tab(self, tabn=None):
-         '''Closes current tab. Supports negative indexing.'''
-@@ -1030,6 +1065,11 @@ class UzblTabbed:
-         tab = self.notebook.get_nth_page(index)
-         self.notebook.set_focus_child(tab)
-         self.update_tablist(index)
-+
-+        if config['save_session'] and config['autosave_session']:
-+            if len(list(self.notebook)) > 1:
-+                self.save_session()
-+
-         return True
- 
- 
-@@ -1038,6 +1078,7 @@ class UzblTabbed:
- 
-         for tab in self.notebook:
-             self.tabs[tab].title_changed(True)
-+        self.update_tablist()
-         return True
- 
- 
-@@ -1261,6 +1302,8 @@ if __name__ == "__main__":
-       help="directory to create socket")
-     parser.add_option('-f', '--fifodir', dest='fifodir',
-       help="directory to create fifo")
-+    parser.add_option('--config-file', dest='config_file',
-+      help="configuration file for all uzbl-browser instances")
- 
-     # Parse command line options
-     (options, uris) = parser.parse_args()
-@@ -1275,6 +1318,15 @@ if __name__ == "__main__":
-         import pprint
-         sys.stderr.write("%s\n" % pprint.pformat(config))
- 
-+    if options.config_file is not None:
-+        if not os.path.exists(options.config_file):
-+            errorstr = "Explicit config file {} does not exist" % (
-+                options.config_file)
-+            error(errorstr)
-+            sys.exit(-1)
-+
-+        config['explicit_config_file'] = options.config_file
-+
-     uzbl = UzblTabbed()
- 
-     if options.socketdir:
-diff --git a/examples/config/config b/examples/config/config
-index 11f1d82..d607cb4 100644
---- a/examples/config/config
-+++ b/examples/config/config
-@@ -8,6 +8,7 @@ set prefix      = @(echo $PREFIX)@
- set data_home   = @(echo $XDG_DATA_HOME)@
- set cache_home  = @(echo $XDG_CACHE_HOME)@
- set config_home = @(echo $XDG_CONFIG_HOME)@
-+set local_storage_path = @data_home/uzbl/databases/
- 
- # Interface paths.
- set fifo_dir   = /tmp
-@@ -70,7 +71,6 @@ set download_handler    = sync_spawn @scripts_dir/download.sh
- @on_event   LOAD_COMMIT    @set_status <span foreground="green">recv</span>
- 
-   # add some javascript to the page for other 'js' and 'script' commands to access later.
-- at on_event   LOAD_COMMIT    js uzbl = {};
- @on_event   LOAD_COMMIT    script @scripts_dir/formfiller.js
- @on_event   LOAD_COMMIT    script @scripts_dir/follow.js
- 
-@@ -86,6 +86,8 @@ set download_handler    = sync_spawn @scripts_dir/download.sh
- # Switch to command mode if anything else is clicked
- @on_event   ROOT_ACTIVE    @set_mode command
- 
-+ at on_event   AUTHENTICATE   spawn @scripts_dir/auth.py "%1" "%2" "%3"
-+
- # Example CONFIG_CHANGED event handler
- #@on_event  CONFIG_CHANGED print Config changed: %1 = %2
- 
-@@ -97,6 +99,10 @@ set download_handler    = sync_spawn @scripts_dir/download.sh
- # Custom CSS can be defined here, including link follower hint styles
- set stylesheet_uri = file://@config_home/uzbl/style.css
- 
-+# If WebKits builtin authentication dialog should be used, if enabling remember
-+# to disable external authentication handlers
-+set enable_builtin_auth = 0
-+
- set show_status       = 1
- set status_top        = 0
- set status_background = #303030
-@@ -138,6 +144,8 @@ set useragent         = Uzbl (Webkit @{WEBKIT_MAJOR}.@{WEBKIT_MINOR}) (@(+uname
- 
- # === Configure cookie blacklist ========================================================
- 
-+set cookie_policy = 0
-+
- # Accept 'session cookies' from uzbl.org (when you have a whitelist all other cookies are dropped)
- #request WHITELIST_COOKIE domain 'uzbl.org$' expires '^$'
- 
-@@ -404,6 +412,9 @@ set formfiller = spawn @scripts_dir/formfiller.sh
- @cbind  gt              = event NEXT_TAB
- @cbind  gT              = event PREV_TAB
- @cbind  gi<index:>_     = event GOTO_TAB %s
-+ at cbind  <Ctrl><Left>    = event MOVE_CURRENT_TAB_LEFT
-+ at cbind  <Ctrl><Right>   = event MOVE_CURRENT_TAB_RIGHT
-+ at cbind  gm<index:>_     = event MOVE_CURRENT_TAB %s
- 
- # Preset loading
- set preset = event PRESET_TABS
-diff --git a/examples/data/plugins/bind.py b/examples/data/plugins/bind.py
-deleted file mode 100644
-index fc8b392..0000000
---- a/examples/data/plugins/bind.py
-+++ /dev/null
-@@ -1,462 +0,0 @@
--'''Plugin provides support for binds in uzbl.
--
--For example:
--  event BIND ZZ = exit          -> bind('ZZ', 'exit')
--  event BIND o _ = uri %s       -> bind('o _', 'uri %s')
--  event BIND fl* = sh 'echo %s' -> bind('fl*', "sh 'echo %s'")
--
--And it is also possible to execute a function on activation:
--  bind('DD', myhandler)
--'''
--
--import sys
--import re
--
--# Commonly used regular expressions.
--MOD_START = re.compile('^<([A-Z][A-Za-z0-9-_]*)>').match
--# Matches <x:y>, <'x':y>, <:'y'>, <x!y>, <'x'!y>, ...
--PROMPTS = '<(\"[^\"]*\"|\'[^\']*\'|[^:!>]*)(:|!)(\"[^\"]*\"|\'[^\']*\'|[^>]*)>'
--FIND_PROMPTS = re.compile(PROMPTS).split
--VALID_MODE = re.compile('^(-|)[A-Za-z0-9][A-Za-z0-9_]*$').match
--
--# For accessing a bind glob stack.
--ON_EXEC, HAS_ARGS, MOD_CMD, GLOB, MORE = range(5)
--
--
--# Custom errors.
--class ArgumentError(Exception): pass
--
--
--class Bindlet(object):
--    '''Per-instance bind status/state tracker.'''
--
--    def __init__(self, uzbl):
--        self.binds = {'global': {}}
--        self.uzbl = uzbl
--        self.depth = 0
--        self.args = []
--        self.last_mode = None
--        self.after_cmds = None
--        self.stack_binds = []
--
--        # A subset of the global mode binds containing non-stack and modkey
--        # activiated binds for use in the stack mode.
--        self.globals = []
--
--
--    def __getitem__(self, key):
--        return self.get_binds(key)
--
--
--    def reset(self):
--        '''Reset the tracker state and return to last mode.'''
--
--        self.depth = 0
--        self.args = []
--        self.after_cmds = None
--        self.stack_binds = []
--
--        if self.last_mode:
--            mode, self.last_mode = self.last_mode, None
--            self.uzbl.config['mode'] = mode
--
--        del self.uzbl.config['keycmd_prompt']
--
--
--    def stack(self, bind, args, depth):
--        '''Enter or add new bind in the next stack level.'''
--
--        if self.depth != depth:
--            if bind not in self.stack_binds:
--                self.stack_binds.append(bind)
--
--            return
--
--        mode = self.uzbl.config.get('mode', None)
--        if mode != 'stack':
--            self.last_mode = mode
--            self.uzbl.config['mode'] = 'stack'
--
--        self.stack_binds = [bind,]
--        self.args += args
--        self.depth += 1
--        self.after_cmds = bind.prompts[depth]
--
--
--    def after(self):
--        '''If a stack was triggered then set the prompt and default value.'''
--
--        if self.after_cmds is None:
--            return
--
--        (prompt, is_cmd, set), self.after_cmds = self.after_cmds, None
--
--        self.uzbl.clear_keycmd()
--        if prompt:
--            self.uzbl.config['keycmd_prompt'] = prompt
--
--        if set and is_cmd:
--            self.uzbl.send(set)
--
--        elif set and not is_cmd:
--            self.uzbl.send('event SET_KEYCMD %s' % set)
--
--
--    def get_binds(self, mode=None):
--        '''Return the mode binds + globals. If we are stacked then return
--        the filtered stack list and modkey & non-stack globals.'''
--
--        if mode is None:
--            mode = self.uzbl.config.get('mode', None)
--
--        if not mode:
--            mode = 'global'
--
--        if self.depth:
--            return self.stack_binds + self.globals
--
--        globals = self.binds['global']
--        if mode not in self.binds or mode == 'global':
--            return filter(None, globals.values())
--
--        binds = dict(globals.items() + self.binds[mode].items())
--        return filter(None, binds.values())
--
--
--    def add_bind(self, mode, glob, bind=None):
--        '''Insert (or override) a bind into the mode bind dict.'''
--
--        if mode not in self.binds:
--            self.binds[mode] = {glob: bind}
--            return
--
--        binds = self.binds[mode]
--        binds[glob] = bind
--
--        if mode == 'global':
--            # Regen the global-globals list.
--            self.globals = []
--            for bind in binds.values():
--                if bind is not None and bind.is_global:
--                    self.globals.append(bind)
--
--
--def ismodbind(glob):
--    '''Return True if the glob specifies a modbind.'''
--
--    return bool(MOD_START(glob))
--
--
--def split_glob(glob):
--    '''Take a string of the form "<Mod1><Mod2>cmd _" and return a list of the
--    modkeys in the glob and the command.'''
--
--    mods = set()
--    while True:
--        match = MOD_START(glob)
--        if not match:
--            break
--
--        end = match.span()[1]
--        mods.add(glob[:end])
--        glob = glob[end:]
--
--    return (mods, glob)
--
--
--class Bind(object):
--
--    # Class attribute to hold the number of Bind classes created.
--    counter = [0,]
--
--    def __init__(self, glob, handler, *args, **kargs):
--        self.is_callable = callable(handler)
--        self._repr_cache = None
--
--        if not glob:
--            raise ArgumentError('glob cannot be blank')
--
--        if self.is_callable:
--            self.function = handler
--            self.args = args
--            self.kargs = kargs
--
--        elif kargs:
--            raise ArgumentError('cannot supply kargs for uzbl commands')
--
--        elif hasattr(handler, '__iter__'):
--            self.commands = handler
--
--        else:
--            self.commands = [handler,] + list(args)
--
--        self.glob = glob
--
--        # Assign unique id.
--        self.counter[0] += 1
--        self.bid = self.counter[0]
--
--        self.split = split = FIND_PROMPTS(glob)
--        self.prompts = []
--        for (prompt, cmd, set) in zip(split[1::4], split[2::4], split[3::4]):
--            prompt, set = map(unquote, [prompt, set])
--            cmd = True if cmd == '!' else False
--            if prompt and prompt[-1] != ":":
--                prompt = "%s:" % prompt
--
--            self.prompts.append((prompt, cmd, set))
--
--        # Check that there is nothing like: fl*<int:>*
--        for glob in split[:-1:4]:
--            if glob.endswith('*'):
--                msg = "token '*' not at the end of a prompt bind: %r" % split
--                raise SyntaxError(msg)
--
--        # Check that there is nothing like: fl<prompt1:><prompt2:>_
--        for glob in split[4::4]:
--            if not glob:
--                msg = 'found null segment after first prompt: %r' % split
--                raise SyntaxError(msg)
--
--        stack = []
--        for (index, glob) in enumerate(reversed(split[::4])):
--            # Is the binding a MODCMD or KEYCMD:
--            mod_cmd = ismodbind(glob)
--
--            # Do we execute on UPDATES or EXEC events?
--            on_exec = True if glob[-1] in ['!', '_'] else False
--
--            # Does the command take arguments?
--            has_args = True if glob[-1] in ['*', '_'] else False
--
--            glob = glob[:-1] if has_args or on_exec else glob
--            mods, glob = split_glob(glob)
--            stack.append((on_exec, has_args, mods, glob, index))
--
--        self.stack = list(reversed(stack))
--        self.is_global = (len(self.stack) == 1 and self.stack[0][MOD_CMD])
--
--
--    def __getitem__(self, depth):
--        '''Get bind info at a depth.'''
--
--        if self.is_global:
--            return self.stack[0]
--
--        return self.stack[depth]
--
--
--    def __repr__(self):
--        if self._repr_cache:
--            return self._repr_cache
--
--        args = ['glob=%r' % self.glob, 'bid=%d' % self.bid]
--
--        if self.is_callable:
--            args.append('function=%r' % self.function)
--            if self.args:
--                args.append('args=%r' % self.args)
--
--            if self.kargs:
--                args.append('kargs=%r' % self.kargs)
--
--        else:
--            cmdlen = len(self.commands)
--            cmds = self.commands[0] if cmdlen == 1 else self.commands
--            args.append('command%s=%r' % ('s' if cmdlen-1 else '', cmds))
--
--        self._repr_cache = '<Bind(%s)>' % ', '.join(args)
--        return self._repr_cache
--
--
--def exec_bind(uzbl, bind, *args, **kargs):
--    '''Execute bind objects.'''
--
--    uzbl.event("EXEC_BIND", bind, args, kargs)
--
--    if bind.is_callable:
--        args += bind.args
--        kargs = dict(bind.kargs.items()+kargs.items())
--        bind.function(uzbl, *args, **kargs)
--        return
--
--    if kargs:
--        raise ArgumentError('cannot supply kargs for uzbl commands')
--
--    commands = []
--    cmd_expand = uzbl.cmd_expand
--    for cmd in bind.commands:
--        cmd = cmd_expand(cmd, args)
--        uzbl.send(cmd)
--
--
--def mode_bind(uzbl, modes, glob, handler=None, *args, **kargs):
--    '''Add a mode bind.'''
--
--    bindlet = uzbl.bindlet
--
--    if not hasattr(modes, '__iter__'):
--        modes = unicode(modes).split(',')
--
--    # Sort and filter binds.
--    modes = filter(None, map(unicode.strip, modes))
--
--    if callable(handler) or (handler is not None and handler.strip()):
--        bind = Bind(glob, handler, *args, **kargs)
--
--    else:
--        bind = None
--
--    for mode in modes:
--        if not VALID_MODE(mode):
--            raise NameError('invalid mode name: %r' % mode)
--
--    for mode in modes:
--        if mode[0] == '-':
--            mode, bind = mode[1:], None
--
--        bindlet.add_bind(mode, glob, bind)
--        uzbl.event('ADDED_MODE_BIND', mode, glob, bind)
--
--
--def bind(uzbl, glob, handler, *args, **kargs):
--    '''Legacy bind function.'''
--
--    mode_bind(uzbl, 'global', glob, handler, *args, **kargs)
--
--
--def parse_mode_bind(uzbl, args):
--    '''Parser for the MODE_BIND event.
--
--    Example events:
--        MODE_BIND <mode>         <bind>        = <command>
--        MODE_BIND command        o<location:>_ = uri %s
--        MODE_BIND insert,command <BackSpace>   = ...
--        MODE_BIND global         ...           = ...
--        MODE_BIND global,-insert ...           = ...
--    '''
--
--    if not args:
--        raise ArgumentError('missing bind arguments')
--
--    split = map(unicode.strip, args.split(' ', 1))
--    if len(split) != 2:
--        raise ArgumentError('missing mode or bind section: %r' % args)
--
--    modes, args = split[0].split(','), split[1]
--    split = map(unicode.strip, args.split('=', 1))
--    if len(split) != 2:
--        raise ArgumentError('missing delimiter in bind section: %r' % args)
--
--    glob, command = split
--    mode_bind(uzbl, modes, glob, command)
--
--
--def parse_bind(uzbl, args):
--    '''Legacy parsing of the BIND event and conversion to the new format.
--
--    Example events:
--        request BIND <bind>        = <command>
--        request BIND o<location:>_ = uri %s
--        request BIND <BackSpace>   = ...
--        request BIND ...           = ...
--    '''
--
--    parse_mode_bind(uzbl, "global %s" % args)
--
--
--def mode_changed(uzbl, mode):
--    '''Clear the stack on all non-stack mode changes.'''
--
--    if mode != 'stack':
--        uzbl.bindlet.reset()
--
--
--def match_and_exec(uzbl, bind, depth, modstate, keylet, bindlet):
--    (on_exec, has_args, mod_cmd, glob, more) = bind[depth]
--    cmd = keylet.modcmd if mod_cmd else keylet.keycmd
--
--    if mod_cmd and modstate != mod_cmd:
--        return False
--
--    if has_args:
--        if not cmd.startswith(glob):
--            return False
--
--        args = [cmd[len(glob):],]
--
--    elif cmd != glob:
--        return False
--
--    else:
--        args = []
--
--    if bind.is_global or (not more and depth == 0):
--        exec_bind(uzbl, bind, *args)
--        if not has_args:
--            uzbl.clear_current()
--
--        return True
--
--    elif more:
--        bindlet.stack(bind, args, depth)
--        (on_exec, has_args, mod_cmd, glob, more) = bind[depth+1]
--        if not on_exec and has_args and not glob and not more:
--            exec_bind(uzbl, bind, *(args+['',]))
--
--        return False
--
--    args = bindlet.args + args
--    exec_bind(uzbl, bind, *args)
--    if not has_args or on_exec:
--        del uzbl.config['mode']
--        bindlet.reset()
--
--    return True
--
--
--def key_event(uzbl, modstate, keylet, mod_cmd=False, on_exec=False):
--    bindlet = uzbl.bindlet
--    depth = bindlet.depth
--    for bind in bindlet.get_binds():
--        t = bind[depth]
--        if (bool(t[MOD_CMD]) != mod_cmd) or (t[ON_EXEC] != on_exec):
--            continue
--
--        if match_and_exec(uzbl, bind, depth, modstate, keylet, bindlet):
--            return
--
--    bindlet.after()
--
--    # Return to the previous mode if the KEYCMD_EXEC keycmd doesn't match any
--    # binds in the stack mode.
--    if on_exec and not mod_cmd and depth and depth == bindlet.depth:
--        del uzbl.config['mode']
--
--
--# plugin init hook
--def init(uzbl):
--    '''Export functions and connect handlers to events.'''
--
--    connect_dict(uzbl, {
--        'BIND':             parse_bind,
--        'MODE_BIND':        parse_mode_bind,
--        'MODE_CHANGED':     mode_changed,
--    })
--
--    # Connect key related events to the key_event function.
--    events = [['KEYCMD_UPDATE', 'KEYCMD_EXEC'],
--              ['MODCMD_UPDATE', 'MODCMD_EXEC']]
--
--    for mod_cmd in range(2):
--        for on_exec in range(2):
--            event = events[mod_cmd][on_exec]
--            connect(uzbl, event, key_event, bool(mod_cmd), bool(on_exec))
--
--    export_dict(uzbl, {
--        'bind':         bind,
--        'mode_bind':    mode_bind,
--        'bindlet':      Bindlet(uzbl),
--    })
--
--# vi: set et ts=4:
-diff --git a/examples/data/plugins/cmd_expand.py b/examples/data/plugins/cmd_expand.py
-deleted file mode 100644
-index b007975..0000000
---- a/examples/data/plugins/cmd_expand.py
-+++ /dev/null
-@@ -1,40 +0,0 @@
--def escape(str):
--    for (level, char) in [(3, '\\'), (2, "'"), (2, '"'), (1, '@')]:
--        str = str.replace(char, (level * '\\') + char)
--
--    return str
--
--
--def cmd_expand(uzbl, cmd, args):
--    '''Exports a function that provides the following
--    expansions in any uzbl command string:
--
--        %s = replace('%s', ' '.join(args))
--        %r = replace('%r', "'%s'" % escaped(' '.join(args)))
--        %1 = replace('%1', arg[0])
--        %2 = replace('%2', arg[1])
--        %n = replace('%n', arg[n-1])
--    '''
--
--    # Ensure (1) all string representable and (2) correct string encoding.
--    args = map(unicode, args)
--
--    # Direct string replace.
--    if '%s' in cmd:
--        cmd = cmd.replace('%s', ' '.join(args))
--
--    # Escaped and quoted string replace.
--    if '%r' in cmd:
--        cmd = cmd.replace('%r', "'%s'" % escape(' '.join(args)))
--
--    # Arg index string replace.
--    for (index, arg) in enumerate(args):
--        index += 1
--        if '%%%d' % index in cmd:
--            cmd = cmd.replace('%%%d' % index, unicode(arg))
--
--    return cmd
--
--# plugin init hook
--def init(uzbl):
--    export(uzbl, 'cmd_expand', cmd_expand)
-diff --git a/examples/data/plugins/completion.py b/examples/data/plugins/completion.py
-deleted file mode 100644
-index e8c7f34..0000000
---- a/examples/data/plugins/completion.py
-+++ /dev/null
-@@ -1,179 +0,0 @@
--'''Keycmd completion.'''
--
--import re
--
--# Completion level
--NONE, ONCE, LIST, COMPLETE = range(4)
--
--# The reverse keyword finding re.
--FIND_SEGMENT = re.compile("(\@[\w_]+|set[\s]+[\w_]+|[\w_]+)$").findall
--
--# Formats
--LIST_FORMAT = "<span> %s </span>"
--ITEM_FORMAT = "<span @hint_style>%s</span>%s"
--
--def escape(str):
--    return str.replace("@", "\@")
--
--
--def get_incomplete_keyword(uzbl):
--    '''Gets the segment of the keycmd leading up to the cursor position and
--    uses a regular expression to search backwards finding parially completed
--    keywords or @variables. Returns a null string if the correct completion
--    conditions aren't met.'''
--
--    keylet = uzbl.keylet
--    left_segment = keylet.keycmd[:keylet.cursor]
--    partial = (FIND_SEGMENT(left_segment) + ['',])[0].lstrip()
--    if partial.startswith('set '):
--        return ('@%s' % partial[4:].lstrip(), True)
--
--    return (partial, False)
--
--
--def stop_completion(uzbl, *args):
--    '''Stop command completion and return the level to NONE.'''
--
--    uzbl.completion.level = NONE
--    del uzbl.config['completion_list']
--
--
--def complete_completion(uzbl, partial, hint, set_completion=False):
--    '''Inject the remaining porition of the keyword into the keycmd then stop
--    the completioning.'''
--
--    if set_completion:
--        remainder = "%s = " % hint[len(partial):]
--
--    else:
--        remainder = "%s " % hint[len(partial):]
--
--    uzbl.inject_keycmd(remainder)
--    stop_completion(uzbl)
--
--
--def partial_completion(uzbl, partial, hint):
--    '''Inject a common portion of the hints into the keycmd.'''
--
--    remainder = hint[len(partial):]
--    uzbl.inject_keycmd(remainder)
--
--
--def update_completion_list(uzbl, *args):
--    '''Checks if the user still has a partially completed keyword under his
--    cursor then update the completion hints list.'''
--
--    partial = get_incomplete_keyword(uzbl)[0]
--    if not partial:
--        return stop_completion(uzbl)
--
--    if uzbl.completion.level < LIST:
--        return
--
--    hints = filter(lambda h: h.startswith(partial), uzbl.completion)
--    if not hints:
--        del uzbl.config['completion_list']
--        return
--
--    j = len(partial)
--    l = [ITEM_FORMAT % (escape(h[:j]), h[j:]) for h in sorted(hints)]
--    uzbl.config['completion_list'] = LIST_FORMAT % ' '.join(l)
--
--
--def start_completion(uzbl, *args):
--
--    comp = uzbl.completion
--    if comp.locked:
--        return
--
--    (partial, set_completion) = get_incomplete_keyword(uzbl)
--    if not partial:
--        return stop_completion(uzbl)
--
--    if comp.level < COMPLETE:
--        comp.level += 1
--
--    hints = filter(lambda h: h.startswith(partial), comp)
--    if not hints:
--        return
--
--    elif len(hints) == 1:
--        comp.lock()
--        complete_completion(uzbl, partial, hints[0], set_completion)
--        comp.unlock()
--        return
--
--    elif partial in hints and comp.level == COMPLETE:
--        comp.lock()
--        complete_completion(uzbl, partial, partial, set_completion)
--        comp.unlock()
--        return
--
--    smalllen, smallest = sorted([(len(h), h) for h in hints])[0]
--    common = ''
--    for i in range(len(partial), smalllen):
--        char, same = smallest[i], True
--        for hint in hints:
--            if hint[i] != char:
--                same = False
--                break
--
--        if not same:
--            break
--
--        common += char
--
--    if common:
--        comp.lock()
--        partial_completion(uzbl, partial, partial+common)
--        comp.unlock()
--
--    update_completion_list(uzbl)
--
--
--def add_builtins(uzbl, builtins):
--    '''Pump the space delimited list of builtin commands into the
--    builtin list.'''
--
--    uzbl.completion.update(builtins.split())
--
--
--def add_config_key(uzbl, key, value):
--    '''Listen on the CONFIG_CHANGED event and add config keys to the variable
--    list for @var<Tab> like expansion support.'''
--
--    uzbl.completion.add("@%s" % key)
--
--
--class Completions(set):
--    def __init__(self):
--        set.__init__(self)
--        self.locked = False
--        self.level = NONE
--
--    def lock(self):
--        self.locked = True
--
--    def unlock(self):
--        self.locked = False
--
--
--def init(uzbl):
--    '''Export functions and connect handlers to events.'''
--
--    export_dict(uzbl, {
--        'completion':       Completions(),
--        'start_completion': start_completion,
--    })
--
--    connect_dict(uzbl, {
--        'BUILTINS':         add_builtins,
--        'CONFIG_CHANGED':   add_config_key,
--        'KEYCMD_CLEARED':   stop_completion,
--        'KEYCMD_EXEC':      stop_completion,
--        'KEYCMD_UPDATE':    update_completion_list,
--        'START_COMPLETION': start_completion,
--        'STOP_COMPLETION':  stop_completion,
--    })
--
--    uzbl.send('dump_config_as_events')
-diff --git a/examples/data/plugins/config.py b/examples/data/plugins/config.py
-deleted file mode 100644
-index c9bdf67..0000000
---- a/examples/data/plugins/config.py
-+++ /dev/null
-@@ -1,91 +0,0 @@
--from re import compile
--from types import BooleanType
--from UserDict import DictMixin
--
--valid_key = compile('^[A-Za-z0-9_\.]+$').match
--
--class Config(DictMixin):
--    def __init__(self, uzbl):
--        self.uzbl = uzbl
--
--        # Create the base dict and map allowed methods to `self`.
--        self.data = data = {}
--
--        methods = ['__contains__', '__getitem__', '__iter__',
--            '__len__',  'get', 'has_key', 'items', 'iteritems',
--            'iterkeys', 'itervalues', 'values']
--
--        for method in methods:
--            setattr(self, method, getattr(data, method))
--
--
--    def __setitem__(self, key, value):
--        self.set(key, value)
--
--    def __delitem__(self, key):
--        self.set(key)
--
--    def update(self, other=None, **kwargs):
--        if other is None:
--            other = {}
--
--        for (key, value) in dict(other).items() + kwargs.items():
--            self[key] = value
--
--
--    def set(self, key, value='', force=False):
--        '''Generates a `set <key> = <value>` command string to send to the
--        current uzbl instance.
--
--        Note that the config dict isn't updated by this function. The config
--        dict is only updated after a successful `VARIABLE_SET ..` event
--        returns from the uzbl instance.'''
--
--        assert valid_key(key)
--
--        if type(value) == BooleanType:
--            value = int(value)
--
--        else:
--            value = unicode(value)
--            assert '\n' not in value
--
--        if not force and key in self and self[key] == value:
--            return
--
--        self.uzbl.send(u'set %s = %s' % (key, value))
--
--
--def parse_set_event(uzbl, args):
--    '''Parse `VARIABLE_SET <var> <type> <value>` event and load the
--    (key, value) pair into the `uzbl.config` dict.'''
--
--    (key, type, raw_value) = (args.split(' ', 2) + ['',])[:3]
--
--    assert valid_key(key)
--    assert type in types
--
--    new_value = types[type](raw_value)
--    old_value = uzbl.config.get(key, None)
--
--    # Update new value.
--    uzbl.config.data[key] = new_value
--
--    if old_value != new_value:
--        uzbl.event('CONFIG_CHANGED', key, new_value)
--
--    # Cleanup null config values.
--    if type == 'str' and not new_value:
--        del uzbl.config.data[key]
--
--
--# plugin init hook
--def init(uzbl):
--    global types
--    types = {'int': int, 'float': float, 'str': unquote}
--    export(uzbl, 'config', Config(uzbl))
--    connect(uzbl, 'VARIABLE_SET', parse_set_event)
--
--# plugin cleanup hook
--def cleanup(uzbl):
--    uzbl.config.data.clear()
-diff --git a/examples/data/plugins/cookies.py b/examples/data/plugins/cookies.py
-deleted file mode 100644
-index bf59e96..0000000
---- a/examples/data/plugins/cookies.py
-+++ /dev/null
-@@ -1,222 +0,0 @@
--""" Basic cookie manager
--    forwards cookies to all other instances connected to the event manager"""
--
--from collections import defaultdict
--import os, re, stat
--
--# these are symbolic names for the components of the cookie tuple
--symbolic = {'domain': 0, 'path':1, 'name':2, 'value':3, 'scheme':4, 'expires':5}
--
--# allows for partial cookies
--# ? allow wildcard in key
--def match(key, cookie):
--    for k,c in zip(key,cookie):
--        if k != c:
--            return False
--    return True
--
--class NullStore(object):
--    def add_cookie(self, rawcookie, cookie):
--        pass
--
--    def delete_cookie(self, rkey, key):
--        pass
--
--class ListStore(list):
--    def add_cookie(self, rawcookie, cookie):
--        self.append(rawcookie)
--
--    def delete_cookie(self, rkey, key):
--        self[:] = [x for x in self if not match(key, splitquoted(x))]
--
--class TextStore(object):
--    def __init__(self, filename):
--        self.filename = filename
--        try:
--          # make sure existing cookie jar is not world-open
--          perm_mode = os.stat(self.filename).st_mode
--          if (perm_mode & (stat.S_IRWXO | stat.S_IRWXG)) > 0:
--              safe_perm = stat.S_IMODE(perm_mode) & ~(stat.S_IRWXO | stat.S_IRWXG)
--              os.chmod(self.filename, safe_perm)
--        except OSError:
--            pass
--
--    def as_event(self, cookie):
--        """Convert cookie.txt row to uzbls cookie event format"""
--        scheme = {
--            'TRUE'  : 'https',
--            'FALSE' : 'http'
--        }
--        extra = ''
--        if cookie[0].startswith("#HttpOnly_"):
--            extra = 'Only'
--            domain = cookie[0][len("#HttpOnly_"):]
--        elif cookie[0].startswith('#'):
--            return None
--        else:
--            domain = cookie[0]
--        try:
--            return (domain,
--                cookie[2],
--                cookie[5],
--                cookie[6],
--                scheme[cookie[3]] + extra,
--                cookie[4])
--        except (KeyError,IndexError):
--            # Let malformed rows pass through like comments
--            return None
--
--    def as_file(self, cookie):
--        """Convert cookie event to cookie.txt row"""
--        secure = {
--            'https' : 'TRUE',
--            'http'  : 'FALSE',
--            'httpsOnly' : 'TRUE',
--            'httpOnly'  : 'FALSE'
--        }
--        http_only = {
--            'https' : '',
--            'http'  : '',
--            'httpsOnly' : '#HttpOnly_',
--            'httpOnly'  : '#HttpOnly_'
--        }
--        return (http_only[cookie[4]] + cookie[0],
--            'TRUE' if cookie[0].startswith('.') else 'FALSE',
--            cookie[1],
--            secure[cookie[4]],
--            cookie[5],
--            cookie[2],
--            cookie[3])
--
--    def add_cookie(self, rawcookie, cookie):
--        assert len(cookie) == 6
--
--        # delete equal cookies (ignoring expire time, value and secure flag)
--        self.delete_cookie(None, cookie[:-3])
--
--        # restrict umask before creating the cookie jar
--        curmask=os.umask(0)
--        os.umask(curmask| stat.S_IRWXO | stat.S_IRWXG)
--
--        first = not os.path.exists(self.filename)
--        with open(self.filename, 'a') as f:
--            if first:
--                print >> f, "# HTTP Cookie File"
--            print >> f, '\t'.join(self.as_file(cookie))
--        os.umask(curmask)
--
--    def delete_cookie(self, rkey, key):
--        if not os.path.exists(self.filename):
--            return
--
--        # restrict umask before creating the cookie jar
--        curmask=os.umask(0)
--        os.umask(curmask | stat.S_IRWXO | stat.S_IRWXG)
--
--        # read all cookies
--        with open(self.filename, 'r') as f:
--            cookies = f.readlines()
--
--        # write those that don't match the cookie to delete
--        with open(self.filename, 'w') as f:
--            for l in cookies:
--                c = self.as_event(l.split('\t'))
--                if c is None or not match(key, c):
--                    print >> f, l,
--        os.umask(curmask)
--
--xdg_data_home = os.environ.get('XDG_DATA_HOME', os.path.join(os.environ['HOME'], '.local/share'))
--DefaultStore = TextStore(os.path.join(xdg_data_home, 'uzbl/cookies.txt'))
--SessionStore = TextStore(os.path.join(xdg_data_home, 'uzbl/session-cookies.txt'))
--
--def match_list(_list, cookie):
--    for matcher in _list:
--        for component, match in matcher:
--            if match(cookie[component]) is None:
--                break
--        else:
--            return True
--    return False
--
--# accept a cookie only when:
--# a. there is no whitelist and the cookie is in the blacklist
--# b. the cookie is in the whitelist and not in the blacklist
--def accept_cookie(uzbl, cookie):
--    if uzbl.cookie_whitelist:
--        if match_list(uzbl.cookie_whitelist, cookie):
--            return not match_list(uzbl.cookie_blacklist, cookie)
--        return False
--
--    return not match_list(uzbl.cookie_blacklist, cookie)
--
--def expires_with_session(uzbl, cookie):
--    return cookie[5] == ''
--
--def get_recipents(uzbl):
--    """ get a list of Uzbl instances to send the cookie too. """
--    # This could be a lot more interesting
--    return [u for u in uzbl.parent.uzbls.values() if u is not uzbl]
--
--def get_store(uzbl, session=False):
--    if session:
--        return SessionStore
--    return DefaultStore
--
--def add_cookie(uzbl, cookie):
--    splitted = splitquoted(cookie)
--    if accept_cookie(uzbl, splitted):
--        for u in get_recipents(uzbl):
--            u.send('add_cookie %s' % cookie)
--
--        get_store(uzbl, expires_with_session(uzbl, splitted)).add_cookie(cookie, splitted)
--    else:
--        logger.debug('cookie %r is blacklisted' % splitted)
--        uzbl.send('delete_cookie %s' % cookie)
--
--def delete_cookie(uzbl, cookie):
--    for u in get_recipents(uzbl):
--        u.send('delete_cookie %s' % cookie)
--
--    splitted = splitquoted(cookie)
--    if len(splitted) == 6:
--        get_store(uzbl, expires_with_session(uzbl, splitted)).delete_cookie(cookie, splitted)
--    else:
--        for store in set([get_store(uzbl, session) for session in (True, False)]):
--            store.delete_cookie(cookie, splitted)
--
--# add a cookie matcher to a whitelist or a blacklist.
--# a matcher is a list of (component, re) tuples that matches a cookie when the
--# "component" part of the cookie matches the regular expression "re".
--# "component" is one of the keys defined in the variable "symbolic" above,
--# or the index of a component of a cookie tuple.
--def add_cookie_matcher(_list, arg):
--    args = splitquoted(arg)
--    mlist = []
--    for (component, regexp) in zip(args[0::2], args[1::2]):
--        try:
--            component = symbolic[component]
--        except KeyError:
--            component = int(component)
--        assert component <= 5
--        mlist.append((component, re.compile(regexp).search))
--    _list.append(mlist)
--
--def blacklist(uzbl, arg):
--    add_cookie_matcher(uzbl.cookie_blacklist, arg)
--
--def whitelist(uzbl, arg):
--    add_cookie_matcher(uzbl.cookie_whitelist, arg)
--
--def init(uzbl):
--    connect_dict(uzbl, {
--        'ADD_COOKIE':       add_cookie,
--        'DELETE_COOKIE':    delete_cookie,
--        'BLACKLIST_COOKIE': blacklist,
--        'WHITELIST_COOKIE': whitelist
--    })
--    export_dict(uzbl, {
--        'cookie_blacklist' : [],
--        'cookie_whitelist' : []
--    })
--
--# vi: set et ts=4:
-diff --git a/examples/data/plugins/downloads.py b/examples/data/plugins/downloads.py
-deleted file mode 100644
-index 8d796ce..0000000
---- a/examples/data/plugins/downloads.py
-+++ /dev/null
-@@ -1,77 +0,0 @@
--# this plugin does a very simple display of download progress. to use it, add
--# @downloads to your status_format.
--
--import os
--ACTIVE_DOWNLOADS = {}
--
--# after a download's status has changed this is called to update the status bar
--def update_download_section(uzbl):
--    global ACTIVE_DOWNLOADS
--
--    if len(ACTIVE_DOWNLOADS):
--        # add a newline before we list downloads
--        result = '
downloads:'
--        for path in ACTIVE_DOWNLOADS:
--            # add each download
--            fn = os.path.basename(path)
--            progress, = ACTIVE_DOWNLOADS[path]
--
--            dl = " %s (%d%%)" % (fn, progress * 100)
--
--            # replace entities to make sure we don't break our markup
--            # (this could be done with an @[]@ expansion in uzbl, but then we
--            # can't use the 
 above to make a new line)
--            dl = dl.replace("&", "&").replace("<", "<")
--            result += dl
--    else:
--        result = ''
--
--    # and the result gets saved to an uzbl variable that can be used in
--    # status_format
--    if uzbl.config.get('downloads', '') != result:
--          uzbl.config['downloads'] = result
--
--def download_started(uzbl, args):
--    # parse the arguments
--    args = splitquoted(args)
--    destination_path = args[0]
--
--    # add to the list of active downloads
--    global ACTIVE_DOWNLOADS
--    ACTIVE_DOWNLOADS[destination_path] = (0.0,)
--
--    # update the progress
--    update_download_section(uzbl)
--
--def download_progress(uzbl, args):
--    # parse the arguments
--    args = splitquoted(args)
--    destination_path = args[0]
--    progress = float(args[1])
--
--    # update the progress
--    global ACTIVE_DOWNLOADS
--    ACTIVE_DOWNLOADS[destination_path] = (progress,)
--
--    # update the status bar variable
--    update_download_section(uzbl)
--
--def download_complete(uzbl, args):
--    # parse the arguments
--    args = splitquoted(args)
--    destination_path = args[0]
--
--    # remove from the list of active downloads
--    global ACTIVE_DOWNLOADS
--    del ACTIVE_DOWNLOADS[destination_path]
--
--    # update the status bar variable
--    update_download_section(uzbl)
--
--# plugin init hook
--def init(uzbl):
--    connect_dict(uzbl, {
--        'DOWNLOAD_STARTED':     download_started,
--        'DOWNLOAD_PROGRESS':    download_progress,
--        'DOWNLOAD_COMPLETE':    download_complete,
--    })
-diff --git a/examples/data/plugins/history.py b/examples/data/plugins/history.py
-deleted file mode 100644
-index f42f86f..0000000
---- a/examples/data/plugins/history.py
-+++ /dev/null
-@@ -1,129 +0,0 @@
--import random
--
--shared_history = {'':[]}
--
--class History(object):
--    def __init__(self, uzbl):
--        self.uzbl = uzbl
--        self._temporary = []
--        self.prompt = ''
--        self.cursor = None
--        self.__temp_tail = False
--        self.search_key = None
--
--    def prev(self):
--        if self.cursor is None:
--            self.cursor = len(self) - 1
--        else:
--            self.cursor -= 1
--
--        if self.search_key:
--            while self.cursor >= 0 and self.search_key not in self[self.cursor]:
--                self.cursor -= 1
--
--        if self.cursor < 0 or len(self) == 0:
--            self.cursor = -1
--            return random.choice(end_messages)
--
--        return self[self.cursor]
--
--    def next(self):
--        if self.cursor is None:
--            return ''
--
--        self.cursor += 1
--
--        if self.search_key:
--            while self.cursor < len(self) and self.search_key not in self[self.cursor]:
--                self.cursor += 1
--
--        if self.cursor >= len(shared_history[self.prompt]):
--            self.cursor = None
--            self.search_key = None
--
--            if self._temporary:
--                return self._temporary.pop()
--            return ''
--
--        return self[self.cursor]
--
--    def change_prompt(self, prompt):
--        self.prompt = prompt
--        self._temporary = []
--        self.__temp_tail = False
--        if prompt not in shared_history:
--            shared_history[prompt] = []
--
--    def search(self, key):
--        self.search_key = key
--        self.cursor = None
--
--    def add(self, cmd):
--        if self._temporary:
--            self._temporary.pop()
--
--        shared_history[self.prompt].append(cmd)
--        self.cursor = None
--        self.search_key = None
--
--    def add_temporary(self, cmd):
--        assert not self._temporary
--
--        self._temporary.append(cmd)
--        self.cursor = len(self) - 1
--
--    def __getitem__(self, i):
--        if i < len(shared_history[self.prompt]):
--            return shared_history[self.prompt][i]
--        return self._temporary[i-len(shared_history)+1]
--
--    def __len__(self):
--        return len(shared_history[self.prompt]) + len(self._temporary)
--
--    def __str__(self):
--        return "(History %s, %s)" % (self.cursor, self.prompt)
--
--def keycmd_exec(uzbl, modstate, keylet):
--    cmd = keylet.get_keycmd()
--    if cmd:
--        uzbl.history.add(cmd)
--
--def history_prev(uzbl, _x):
--    cmd = uzbl.keylet.get_keycmd()
--    if uzbl.history.cursor is None and cmd:
--        uzbl.history.add_temporary(cmd)
--
--    uzbl.set_keycmd(uzbl.history.prev())
--    uzbl.logger.debug('PREV %s' % uzbl.history)
--
--def history_next(uzbl, _x):
--    cmd = uzbl.keylet.get_keycmd()
--
--    uzbl.set_keycmd(uzbl.history.next())
--    uzbl.logger.debug('NEXT %s' % uzbl.history)
--
--def history_search(uzbl, key):
--    uzbl.history.search(key)
--    uzbl.send('event HISTORY_PREV')
--    uzbl.logger.debug('SEARCH %s %s' % (key, uzbl.history))
--
--end_messages = ('Look behind you, A three-headed monkey!', 'error #4: static from nylon underwear.', 'error #5: static from plastic slide rules.', 'error #6: global warming.', 'error #9: doppler effect.', 'error #16: somebody was calculating pi on the server.', 'error #19: floating point processor overflow.', 'error #21: POSIX compliance problem.', 'error #25: Decreasing electron flux.', 'error #26: first Saturday after first full moon in Winter.', 'error #64: CPU needs recalibration.', 'error #116: the real ttys became pseudo ttys and vice-versa.', 'error #229: wrong polarity of neutron flow.', 'error #330: quantum decoherence.', 'error #388: Bad user karma.', 'error #407: Route flapping at the NAP.', 'error #435: Internet shut down due to maintenance.')
--
--# plugin init hook
--def init(uzbl):
--    connect_dict(uzbl, {
--        'KEYCMD_EXEC': keycmd_exec,
--        'HISTORY_PREV': history_prev,
--        'HISTORY_NEXT': history_next,
--        'HISTORY_SEARCH': history_search
--    })
--
--    export_dict(uzbl, {
--        'history' : History(uzbl)
--    })
--
--# plugin after hook
--def after(uzbl):
--    uzbl.on_set('keycmd_prompt', lambda uzbl, k, v: uzbl.history.change_prompt(v))
--
--# vi: set et ts=4:
-diff --git a/examples/data/plugins/keycmd.py b/examples/data/plugins/keycmd.py
-deleted file mode 100644
-index 1bb70e3..0000000
---- a/examples/data/plugins/keycmd.py
-+++ /dev/null
-@@ -1,423 +0,0 @@
--import re
--
--# Keycmd format which includes the markup for the cursor.
--KEYCMD_FORMAT = "%s<span @cursor_style>%s</span>%s"
--MODCMD_FORMAT = "<span> %s </span>"
--
--
--def escape(str):
--    for char in ['\\', '@']:
--        str = str.replace(char, '\\'+char)
--
--    return str
--
--
--def uzbl_escape(str):
--    return "@[%s]@" % escape(str) if str else ''
--
--
--class Keylet(object):
--    '''Small per-instance object that tracks characters typed.'''
--
--    def __init__(self):
--        # Modcmd tracking
--        self.modcmd = ''
--        self.is_modcmd = False
--
--        # Keycmd tracking
--        self.keycmd = ''
--        self.cursor = 0
--
--        self.modmaps = {}
--        self.ignores = {}
--
--
--    def get_keycmd(self):
--        '''Get the keycmd-part of the keylet.'''
--
--        return self.keycmd
--
--
--    def get_modcmd(self):
--        '''Get the modcmd-part of the keylet.'''
--
--        if not self.is_modcmd:
--            return ''
--
--        return self.modcmd
--
--
--    def modmap_key(self, key):
--        '''Make some obscure names for some keys friendlier.'''
--
--        if key in self.modmaps:
--            return self.modmaps[key]
--
--        elif key.endswith('_L') or key.endswith('_R'):
--            # Remove left-right discrimination and try again.
--            return self.modmap_key(key[:-2])
--
--        else:
--            return key
--
--
--    def key_ignored(self, key):
--        '''Check if the given key is ignored by any ignore rules.'''
--
--        for (glob, match) in self.ignores.items():
--            if match(key):
--                return True
--
--        return False
--
--
--    def __repr__(self):
--        '''Return a string representation of the keylet.'''
--
--        l = []
--        if self.is_modcmd:
--            l.append('modcmd=%r' % self.get_modcmd())
--
--        if self.keycmd:
--            l.append('keycmd=%r' % self.get_keycmd())
--
--        return '<keylet(%s)>' % ', '.join(l)
--
--
--def add_modmap(uzbl, key, map):
--    '''Add modmaps.
--
--    Examples:
--        set modmap = request MODMAP
--        @modmap <Control> <Ctrl>
--        @modmap <ISO_Left_Tab> <Shift-Tab>
--        ...
--
--    Then:
--        @bind <Shift-Tab> = <command1>
--        @bind <Ctrl>x = <command2>
--        ...
--
--    '''
--
--    assert len(key)
--    modmaps = uzbl.keylet.modmaps
--
--    modmaps[key.strip('<>')] = map.strip('<>')
--    uzbl.event("NEW_MODMAP", key, map)
--
--
--def modmap_parse(uzbl, map):
--    '''Parse a modmap definiton.'''
--
--    split = [s.strip() for s in map.split(' ') if s.split()]
--
--    if not split or len(split) > 2:
--        raise Exception('Invalid modmap arugments: %r' % map)
--
--    add_modmap(uzbl, *split)
--
--
--def add_key_ignore(uzbl, glob):
--    '''Add an ignore definition.
--
--    Examples:
--        set ignore_key = request IGNORE_KEY
--        @ignore_key <Shift>
--        @ignore_key <ISO_*>
--        ...
--    '''
--
--    assert len(glob) > 1
--    ignores = uzbl.keylet.ignores
--
--    glob = "<%s>" % glob.strip("<> ")
--    restr = glob.replace('*', '[^\s]*')
--    match = re.compile(restr).match
--
--    ignores[glob] = match
--    uzbl.event('NEW_KEY_IGNORE', glob)
--
--
--def clear_keycmd(uzbl, *args):
--    '''Clear the keycmd for this uzbl instance.'''
--
--    k = uzbl.keylet
--    k.keycmd = ''
--    k.cursor = 0
--    del uzbl.config['keycmd']
--    uzbl.event('KEYCMD_CLEARED')
--
--
--def clear_modcmd(uzbl):
--    '''Clear the modcmd for this uzbl instance.'''
--
--    k = uzbl.keylet
--    k.modcmd = ''
--    k.is_modcmd = False
--
--    del uzbl.config['modcmd']
--    uzbl.event('MODCMD_CLEARED')
--
--
--def clear_current(uzbl):
--    '''Clear the modcmd if is_modcmd else clear keycmd.'''
--
--    if uzbl.keylet.is_modcmd:
--        clear_modcmd(uzbl)
--
--    else:
--        clear_keycmd(uzbl)
--
--
--def update_event(uzbl, modstate, k, execute=True):
--    '''Raise keycmd & modcmd update events.'''
--
--    keycmd, modcmd = k.get_keycmd(), ''.join(modstate) + k.get_modcmd()
--
--    if k.is_modcmd:
--        logger.debug('modcmd_update, %s' % modcmd)
--        uzbl.event('MODCMD_UPDATE', modstate, k)
--
--    else:
--        logger.debug('keycmd_update, %s' % keycmd)
--        uzbl.event('KEYCMD_UPDATE', modstate, k)
--
--    if uzbl.config.get('modcmd_updates', '1') == '1':
--        new_modcmd = ''.join(modstate) + k.get_modcmd()
--        if not new_modcmd or not k.is_modcmd:
--            del uzbl.config['modcmd']
--
--        elif new_modcmd == modcmd:
--            uzbl.config['modcmd'] = MODCMD_FORMAT % uzbl_escape(modcmd)
--
--    if uzbl.config.get('keycmd_events', '1') != '1':
--        return
--
--    new_keycmd = k.get_keycmd()
--    if not new_keycmd:
--        del uzbl.config['keycmd']
--
--    elif new_keycmd == keycmd:
--        # Generate the pango markup for the cursor in the keycmd.
--        curchar = keycmd[k.cursor] if k.cursor < len(keycmd) else ' '
--        chunks = [keycmd[:k.cursor], curchar, keycmd[k.cursor+1:]]
--        value = KEYCMD_FORMAT % tuple(map(uzbl_escape, chunks))
--
--        uzbl.config['keycmd'] = value
--
--
--def inject_str(str, index, inj):
--    '''Inject a string into string at at given index.'''
--
--    return "%s%s%s" % (str[:index], inj, str[index:])
--
--
--def parse_key_event(uzbl, key):
--    ''' Build a set from the modstate part of the event, and pass all keys through modmap '''
--    keylet = uzbl.keylet
--
--    modstate, key = splitquoted(key)
--    modstate = set(['<%s>' % keylet.modmap_key(k) for k in modstate.split('|') if k])
--    
--    key = keylet.modmap_key(key)
--    return modstate, key
--
--
--def key_press(uzbl, key):
--    '''Handle KEY_PRESS events. Things done by this function include:
--
--    1. Ignore all shift key presses (shift can be detected by capital chars)
--    2. In non-modcmd mode:
--         a. append char to keycmd
--    3. If not in modcmd mode and a modkey was pressed set modcmd mode.
--    4. Keycmd is updated and events raised if anything is changed.'''
--
--    k = uzbl.keylet
--    modstate, key = parse_key_event(uzbl, key)
--    k.is_modcmd = any(not k.key_ignored(m) for m in modstate)
--
--    logger.debug('key press modstate=%s' % str(modstate))
--    if key.lower() == 'space' and not k.is_modcmd and k.keycmd:
--        k.keycmd = inject_str(k.keycmd, k.cursor, ' ')
--        k.cursor += 1
--
--    elif not k.is_modcmd and len(key) == 1:
--        if uzbl.config.get('keycmd_events', '1') != '1':
--            # TODO, make a note on what's going on here
--            k.keycmd = ''
--            k.cursor = 0
--            del uzbl.config['keycmd']
--            return
--
--        k.keycmd = inject_str(k.keycmd, k.cursor, key)
--        k.cursor += 1
--
--    elif len(key) == 1:
--        k.modcmd += key
--
--    else:
--        if not k.key_ignored('<%s>' % key):
--            modstate.add('<%s>' % key)
--            k.is_modcmd = True
--
--    update_event(uzbl, modstate, k)
--
--
--def key_release(uzbl, key):
--    '''Respond to KEY_RELEASE event. Things done by this function include:
--
--    1. If in a mod-command then raise a MODCMD_EXEC.
--    2. Update the keycmd uzbl variable if anything changed.'''
--    k = uzbl.keylet
--    modstate, key = parse_key_event(uzbl, key)
--
--    if len(key) > 1:
--        if k.is_modcmd:
--            uzbl.event('MODCMD_EXEC', modstate, k)
--
--        clear_modcmd(uzbl)
--
--
--def set_keycmd(uzbl, keycmd):
--    '''Allow setting of the keycmd externally.'''
--
--    k = uzbl.keylet
--    k.keycmd = keycmd
--    k.cursor = len(keycmd)
--    update_event(uzbl, set(), k, False)
--
--
--def inject_keycmd(uzbl, keycmd):
--    '''Allow injecting of a string into the keycmd at the cursor position.'''
--
--    k = uzbl.keylet
--    k.keycmd = inject_str(k.keycmd, k.cursor, keycmd)
--    k.cursor += len(keycmd)
--    update_event(uzbl, set(), k, False)
--
--
--def append_keycmd(uzbl, keycmd):
--    '''Allow appening of a string to the keycmd.'''
--
--    k = uzbl.keylet
--    k.keycmd += keycmd
--    k.cursor = len(k.keycmd)
--    update_event(uzbl, set(), k, False)
--
--
--def keycmd_strip_word(uzbl, seps):
--    ''' Removes the last word from the keycmd, similar to readline ^W '''
--
--    seps = seps or ' '
--    k = uzbl.keylet
--    if not k.keycmd:
--        return
--
--    head, tail = k.keycmd[:k.cursor].rstrip(seps), k.keycmd[k.cursor:]
--    rfind = -1
--    for sep in seps:
--        p = head.rfind(sep)
--        if p >= 0 and rfind < p + 1:
--            rfind = p + 1
--    if rfind == len(head) and head[-1] in seps:
--        rfind -= 1
--    head = head[:rfind] if rfind + 1 else ''
--    k.keycmd = head + tail
--    k.cursor = len(head)
--    update_event(uzbl, set(), k, False)
--
--
--def keycmd_backspace(uzbl, *args):
--    '''Removes the character at the cursor position in the keycmd.'''
--
--    k = uzbl.keylet
--    if not k.keycmd or not k.cursor:
--        return
--
--    k.keycmd = k.keycmd[:k.cursor-1] + k.keycmd[k.cursor:]
--    k.cursor -= 1
--    update_event(uzbl, set(), k, False)
--
--
--def keycmd_delete(uzbl, *args):
--    '''Removes the character after the cursor position in the keycmd.'''
--
--    k = uzbl.keylet
--    if not k.keycmd:
--        return
--
--    k.keycmd = k.keycmd[:k.cursor] + k.keycmd[k.cursor+1:]
--    update_event(uzbl, set(), k, False)
--
--
--def keycmd_exec_current(uzbl, *args):
--    '''Raise a KEYCMD_EXEC with the current keylet and then clear the
--    keycmd.'''
--
--    uzbl.event('KEYCMD_EXEC', set(), uzbl.keylet)
--    clear_keycmd(uzbl)
--
--
--def set_cursor_pos(uzbl, index):
--    '''Allow setting of the cursor position externally. Supports negative
--    indexing and relative stepping with '+' and '-'.'''
--
--    k = uzbl.keylet
--    if index == '-':
--        cursor = k.cursor - 1
--
--    elif index == '+':
--        cursor = k.cursor + 1
--
--    else:
--        cursor = int(index.strip())
--        if cursor < 0:
--            cursor = len(k.keycmd) + cursor + 1
--
--    if cursor < 0:
--        cursor = 0
--
--    if cursor > len(k.keycmd):
--        cursor = len(k.keycmd)
--
--    k.cursor = cursor
--    update_event(uzbl, set(), k, False)
--
--
--# plugin init hook
--def init(uzbl):
--    '''Export functions and connect handlers to events.'''
--
--    connect_dict(uzbl, {
--        'APPEND_KEYCMD':        append_keycmd,
--        'IGNORE_KEY':           add_key_ignore,
--        'INJECT_KEYCMD':        inject_keycmd,
--        'KEYCMD_BACKSPACE':     keycmd_backspace,
--        'KEYCMD_DELETE':        keycmd_delete,
--        'KEYCMD_EXEC_CURRENT':  keycmd_exec_current,
--        'KEYCMD_STRIP_WORD':    keycmd_strip_word,
--        'KEYCMD_CLEAR':         clear_keycmd,
--        'KEY_PRESS':            key_press,
--        'KEY_RELEASE':          key_release,
--        'MOD_PRESS':            key_press,
--        'MOD_RELEASE':          key_release,
--        'MODMAP':               modmap_parse,
--        'SET_CURSOR_POS':       set_cursor_pos,
--        'SET_KEYCMD':           set_keycmd,
--    })
--
--    export_dict(uzbl, {
--        'add_key_ignore':       add_key_ignore,
--        'add_modmap':           add_modmap,
--        'append_keycmd':        append_keycmd,
--        'clear_current':        clear_current,
--        'clear_keycmd':         clear_keycmd,
--        'clear_modcmd':         clear_modcmd,
--        'inject_keycmd':        inject_keycmd,
--        'keylet':               Keylet(),
--        'set_cursor_pos':       set_cursor_pos,
--        'set_keycmd':           set_keycmd,
--    })
--
--# vi: set et ts=4:
-diff --git a/examples/data/plugins/mode.py b/examples/data/plugins/mode.py
-deleted file mode 100644
-index e0de706..0000000
---- a/examples/data/plugins/mode.py
-+++ /dev/null
-@@ -1,68 +0,0 @@
--from collections import defaultdict
--
--def parse_mode_config(uzbl, args):
--    '''Parse `MODE_CONFIG <mode> <var> = <value>` event and update config if
--    the `<mode>` is the current mode.'''
--
--    ustrip = unicode.strip
--    args = unicode(args)
--
--    assert args.strip(), "missing mode config args"
--    (mode, args) = map(ustrip, (args.strip().split(' ', 1) + ['',])[:2])
--
--    assert args.strip(), "missing mode config set arg"
--    (key, value) = map(ustrip, (args.strip().split('=', 1) + [None,])[:2])
--    assert key and value is not None, "invalid mode config set syntax"
--
--    uzbl.mode_config[mode][key] = value
--    if uzbl.config.get('mode', None) == mode:
--        uzbl.config[key] = value
--
--
--def default_mode_updated(uzbl, var, mode):
--    if mode and not uzbl.config.get('mode', None):
--        logger.debug('setting mode to default %r' % mode)
--        uzbl.config['mode'] = mode
--
--
--def mode_updated(uzbl, var, mode):
--    if not mode:
--        mode = uzbl.config.get('default_mode', 'command')
--        logger.debug('setting mode to default %r' % mode)
--        uzbl.config['mode'] = mode
--        return
--
--    # Load mode config
--    mode_config = uzbl.mode_config.get(mode, None)
--    if mode_config:
--        uzbl.config.update(mode_config)
--
--    uzbl.send('event MODE_CONFIRM %s' % mode)
--
--
--def confirm_change(uzbl, mode):
--    if mode and uzbl.config.get('mode', None) == mode:
--        uzbl.event('MODE_CHANGED', mode)
--
--
--# plugin init hook
--def init(uzbl):
--    require('config')
--    require('on_set')
--
--    # Usage `uzbl.mode_config[mode][key] = value`
--    export(uzbl, 'mode_config', defaultdict(dict))
--
--    connect_dict(uzbl, {
--        'MODE_CONFIG':  parse_mode_config,
--        'MODE_CONFIRM': confirm_change,
--    })
--
--# plugin after hook
--def after(uzbl):
--    uzbl.on_set('mode', mode_updated)
--    uzbl.on_set('default_mode', default_mode_updated)
--
--# plugin cleanup hook
--def cleanup(uzbl):
--    uzbl.mode_config.clear()
-diff --git a/examples/data/plugins/on_event.py b/examples/data/plugins/on_event.py
-deleted file mode 100644
-index 32f09e2..0000000
---- a/examples/data/plugins/on_event.py
-+++ /dev/null
-@@ -1,88 +0,0 @@
--'''Plugin provides arbitrary binding of uzbl events to uzbl commands.
--
--Formatting options:
--  %s = space separated string of the arguments
--  %r = escaped and quoted version of %s
--  %1 = argument 1
--  %2 = argument 2
--  %n = argument n
--
--Usage:
--  request ON_EVENT LINK_HOVER set selected_uri = $1
--    --> LINK_HOVER http://uzbl.org/
--    <-- set selected_uri = http://uzbl.org/
--
--  request ON_EVENT CONFIG_CHANGED print Config changed: %1 = %2
--    --> CONFIG_CHANGED selected_uri http://uzbl.org/
--    <-- print Config changed: selected_uri = http://uzbl.org/
--'''
--
--import sys
--import re
--
--def event_handler(uzbl, *args, **kargs):
--    '''This function handles all the events being watched by various
--    on_event definitions and responds accordingly.'''
--
--    # Could be connected to a EM internal event that can use anything as args
--    if len(args) == 1 and isinstance(args[0], basestring):
--        args = splitquoted(args[0])
--
--    events = uzbl.on_events
--    event = kargs['on_event']
--    if event not in events:
--        return
--
--    commands = events[event]
--    cmd_expand = uzbl.cmd_expand
--    for cmd in commands:
--        cmd = cmd_expand(cmd, args)
--        uzbl.send(cmd)
--
--
--def on_event(uzbl, event, cmd):
--    '''Add a new event to watch and respond to.'''
--
--    event = event.upper()
--    events = uzbl.on_events
--    if event not in events:
--        connect(uzbl, event, event_handler, on_event=event)
--        events[event] = []
--
--    cmds = events[event]
--    if cmd not in cmds:
--        cmds.append(cmd)
--
--
--def parse_on_event(uzbl, args):
--    '''Parse ON_EVENT events and pass them to the on_event function.
--
--    Syntax: "event ON_EVENT <EVENT_NAME> commands".'''
--
--    args = args.strip()
--    assert args, 'missing on event arguments'
--
--    (event, command) = (args.split(' ', 1) + ['',])[:2]
--    assert event and command, 'missing on event command'
--    on_event(uzbl, event, command)
--
--
--# plugin init hook
--def init(uzbl):
--    '''Export functions and connect handlers to events.'''
--
--    connect(uzbl, 'ON_EVENT', parse_on_event)
--
--    export_dict(uzbl, {
--        'on_event':     on_event,
--        'on_events':    {},
--    })
--
--# plugin cleanup hook
--def cleanup(uzbl):
--    for handlers in uzbl.on_events.values():
--        del handlers[:]
--
--    uzbl.on_events.clear()
--
--# vi: set et ts=4:
-diff --git a/examples/data/plugins/on_set.py b/examples/data/plugins/on_set.py
-deleted file mode 100644
-index 130b816..0000000
---- a/examples/data/plugins/on_set.py
-+++ /dev/null
-@@ -1,92 +0,0 @@
--from re import compile
--from functools import partial
--
--valid_glob = compile('^[A-Za-z0-9_\*\.]+$').match
--
--def make_matcher(glob):
--    '''Make matcher function from simple glob.'''
--
--    pattern = "^%s$" % glob.replace('*', '[^\s]*')
--    return compile(pattern).match
--
--
--def exec_handlers(uzbl, handlers, key, arg):
--    '''Execute the on_set handlers that matched the key.'''
--
--    for handler in handlers:
--        if callable(handler):
--            handler(key, arg)
--
--        else:
--            uzbl.send(uzbl.cmd_expand(handler, [key, arg]))
--
--
--def check_for_handlers(uzbl, key, arg):
--    '''Check for handlers for the current key.'''
--
--    for (matcher, handlers) in uzbl.on_sets.values():
--        if matcher(key):
--            exec_handlers(uzbl, handlers, key, arg)
--
--
--def on_set(uzbl, glob, handler, prepend=True):
--    '''Add a new handler for a config key change.
--
--    Structure of the `uzbl.on_sets` dict:
--      { glob : ( glob matcher function, handlers list ), .. }
--    '''
--
--    assert valid_glob(glob)
--
--    while '**' in glob:
--        glob = glob.replace('**', '*')
--
--    if callable(handler):
--        orig_handler = handler
--        if prepend:
--            handler = partial(handler, uzbl)
--
--    else:
--        orig_handler = handler = unicode(handler)
--
--    if glob in uzbl.on_sets:
--        (matcher, handlers) = uzbl.on_sets[glob]
--        handlers.append(handler)
--
--    else:
--        matcher = make_matcher(glob)
--        uzbl.on_sets[glob] = (matcher, [handler,])
--
--    uzbl.logger.info('on set %r call %r' % (glob, orig_handler))
--
--
--def parse_on_set(uzbl, args):
--    '''Parse `ON_SET <glob> <command>` event then pass arguments to the
--    `on_set(..)` function.'''
--
--    (glob, command) = (args.split(' ', 1) + [None,])[:2]
--    assert glob and command and valid_glob(glob)
--    on_set(uzbl, glob, command)
--
--
--# plugins init hook
--def init(uzbl):
--    require('config')
--    require('cmd_expand')
--
--    export_dict(uzbl, {
--        'on_sets':  {},
--        'on_set':   on_set,
--    })
--
--    connect_dict(uzbl, {
--        'ON_SET':           parse_on_set,
--        'CONFIG_CHANGED':   check_for_handlers,
--    })
--
--# plugins cleanup hook
--def cleanup(uzbl):
--    for (matcher, handlers) in uzbl.on_sets.values():
--        del handlers[:]
--
--    uzbl.on_sets.clear()
-diff --git a/examples/data/plugins/progress_bar.py b/examples/data/plugins/progress_bar.py
-deleted file mode 100644
-index b2edffc..0000000
---- a/examples/data/plugins/progress_bar.py
-+++ /dev/null
-@@ -1,93 +0,0 @@
--UPDATES = 0
--
--def update_progress(uzbl, progress=None):
--    '''Updates the progress.output variable on LOAD_PROGRESS update.
--
--    The current substitution options are:
--        %d = done char * done
--        %p = pending char * remaining
--        %c = percent done
--        %i = int done
--        %s = -\|/ spinner
--        %t = percent pending
--        %o = int pending
--        %r = sprites
--
--    Default configuration options:
--        progress.format  = [%d>%p]%c
--        progress.width   = 8
--        progress.done    = =
--        progress.pending =
--        progress.spinner = -\|/
--        progress.sprites = loading
--    '''
--
--    global UPDATES
--
--    if progress is None:
--        UPDATES = 0
--        progress = 100
--
--    else:
--        UPDATES += 1
--        progress = int(progress)
--
--    # Get progress config vars.
--    format = uzbl.config.get('progress.format', '[%d>%p]%c')
--    width = int(uzbl.config.get('progress.width', 8))
--    done_symbol = uzbl.config.get('progress.done', '=')
--    pend = uzbl.config.get('progress.pending', None)
--    pending_symbol = pend if pend else ' '
--
--    # Inflate the done and pending bars to stop the progress bar
--    # jumping around.
--    if '%c' in format or '%i' in format:
--        count = format.count('%c') + format.count('%i')
--        width += (3-len(str(progress))) * count
--
--    if '%t' in format or '%o' in format:
--        count = format.count('%t') + format.count('%o')
--        width += (3-len(str(100-progress))) * count
--
--    done = int(((progress/100.0)*width)+0.5)
--    pending = width - done
--
--    if '%d' in format:
--        format = format.replace('%d', done_symbol * done)
--
--    if '%p' in format:
--        format = format.replace('%p', pending_symbol * pending)
--
--    if '%c' in format:
--        format = format.replace('%c', '%d%%' % progress)
--
--    if '%i' in format:
--        format = format.replace('%i', '%d' % progress)
--
--    if '%t' in format:
--        format = format.replace('%t', '%d%%' % (100-progress))
--
--    if '%o' in format:
--        format = format.replace('%o', '%d' % (100-progress))
--
--    if '%s' in format:
--        spinner = uzbl.config.get('progress.spinner', '-\\|/')
--        index = 0 if progress == 100 else UPDATES % len(spinner)
--        spin = '\\\\' if spinner[index] == '\\' else spinner[index]
--        format = format.replace('%s', spin)
--
--    if '%r' in format:
--        sprites = uzbl.config.get('progress.sprites', 'loading')
--        index = int(((progress/100.0)*len(sprites))+0.5)-1
--        sprite = '\\\\' if sprites[index] == '\\' else sprites[index]
--        format = format.replace('%r', sprite)
--
--    if uzbl.config.get('progress.output', None) != format:
--        uzbl.config['progress.output'] = format
--
--# plugin init hook
--def init(uzbl):
--    connect_dict(uzbl, {
--        'LOAD_COMMIT':      lambda uzbl, uri: update_progress(uzbl),
--        'LOAD_PROGRESS':    update_progress,
--    })
-diff --git a/examples/data/scripts/auth.py b/examples/data/scripts/auth.py
-index 49fa41e..dbf58dc 100755
---- a/examples/data/scripts/auth.py
-+++ b/examples/data/scripts/auth.py
-@@ -1,5 +1,6 @@
- #!/usr/bin/env python
- 
-+import os
- import gtk
- import sys
- 
-@@ -41,13 +42,20 @@ def getText(authInfo, authHost, authRealm):
-     dialog.show_all()
-     rv = dialog.run()
- 
--    output = login.get_text() + "\n" + password.get_text()
-+    output = {
-+        'username': login.get_text(),
-+        'password': password.get_text()
-+    }
-     dialog.destroy()
-     return rv, output
- 
- if __name__ == '__main__':
--    rv, output = getText(sys.argv[1], sys.argv[2], sys.argv[3])
-+    fifo = open(os.environ.get('UZBL_FIFO'), 'w')
-+    me, info, host, realm = sys.argv
-+    rv, output = getText(info, host, realm)
-     if (rv == gtk.RESPONSE_OK):
--        print output;
-+        print >> fifo, 'auth "%s" "%s" "%s"' % (
-+            info, output['username'], output['password']
-+        )
-     else:
-         exit(1)
-diff --git a/examples/data/scripts/follow.js b/examples/data/scripts/follow.js
-index 83bbf55..0afeec3 100644
---- a/examples/data/scripts/follow.js
-+++ b/examples/data/scripts/follow.js
-@@ -12,6 +12,7 @@
- 
- // Globals
- uzbldivid = 'uzbl_link_hints';
-+var uzbl = uzbl || {};
- 
- uzbl.follow = function() {
-     // Export
-diff --git a/examples/data/scripts/formfiller.js b/examples/data/scripts/formfiller.js
-index 06db648..9c56f7b 100644
---- a/examples/data/scripts/formfiller.js
-+++ b/examples/data/scripts/formfiller.js
-@@ -1,3 +1,5 @@
-+var uzbl = uzbl || {};
-+
- uzbl.formfiller = {
- 
-     // this is pointlessly duplicated in uzbl.follow
-diff --git a/examples/data/scripts/history.sh b/examples/data/scripts/history.sh
-index 0709b5e..2d96a07 100755
---- a/examples/data/scripts/history.sh
-+++ b/examples/data/scripts/history.sh
-@@ -1,5 +1,7 @@
- #!/bin/sh
- 
-+[ -n "$UZBL_PRIVATE" ] && exit 0
-+
<Skipped 7251 lines>
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/uzbl.git/commitdiff/099006da4d6c9d498728aa7ec4ffe6727ce41ab1



More information about the pld-cvs-commit mailing list