;;; ezbl.el --- Emacs interface for Uzbl (uzbl.org) ;; ;; Version: 0.4 ;; URL: http://github.com/dhax/ezbl ;; This file 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, or (at your option) any later version. ;; This file 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 ;; GNU Emacs; see the file COPYING. If not, write to the Free Software ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ;; USA. ;;; Commentary: ;; ;; Uzbl version 2009.11.30 or greater is required. Ezbl will not work with ;; older versions. ;; ;; Run `ezbl-open' to start a Uzbl instance and browse to a URL. Also, check ;; `ezbl-mode' for a listing of the key bindings of Ezbl. (eval-when-compile (require 'cl)) (require 'url-cookie) (defgroup ezbl nil "Settings for Ezbl, the Emacs frontend for Uzbl.") (defcustom ezbl-exec-path (or (executable-find "uzbl-core") "/usr/bin/uzbl-core") "The location of the Uzbl executable." :group 'ezbl :type 'file) (defcustom ezbl-cookie-socket "/tmp/ezbl-cookies" "The location of the socket through which to handle cookies." :group 'ezbl :type 'file) (defvar ezbl-inst-list nil "An alist of Uzbl instances and their pids. Has the format: ((pid . instance) (pid2 . instance2)) The values are instances of the `ezbl-inst' struct.") (defvar ezbl-inst nil "A buffer-local variable storing the current Ezbl instance. It is an instance of the `ezbl-inst' struct.") (defvar ezbl-cookie-process nil "The process which is listening for cookie requests from Uzbl processes.") (defvar ezbl-initialized nil "Keeps track of whether or not Ezbl has been initialized. This should only be set by `ezbl-init'.") (defconst ezbl-inst-slots '(args process pid output-buffer display-buffer vars) "A list of the slot names in the `ezbl-inst' structure. `defstruct' does not keep a list of the fields of the struct for later use, so do this manually.") (eval `(defstruct ezbl-inst "A structure containing the properties of an Ezbl instance." ,@ezbl-inst-slots)) (defconst ezbl-inst-get-first '(ezbl-inst-get-first nil ;; protected t ;; enabled (advice . (lambda () (ad-set-arg 0 (ezbl-inst-get (ad-get-arg 0)))))) "Computed advice to apply to each of the `ezbl-inst' slot accessors.") (defconst ezbl-output-buffer-format " *ezbl-output-%s*" "The format used for transforming ezbl instance names into buffer names.") (defconst ezbl-display-buffer-format "*ezbl-display-%s*" "The format used for transforming ezbl instance names into buffer names.") (defvar ezbl-commands '(((name . "back") (format . "back") (interactive . "U") (key-binding . "C-c C-b") (doc . "Move backwards in the browser history.")) ((name . "forward") (format . "forward") (interactive . "U") (key-binding . "C-c C-f") (doc . "Move forwards in the browser history.")) ((name . "scroll") (format . "scroll ") (interactive . "U\nnScroll amount: ") (key-binding . "C-c C-v") (doc . "Scroll in DIRECTION by ARGUMENT. * argument can be `begin`, `end`, or an amount given in pixels or as a percentage of the size of the view. * set the amount to 100% to scroll a whole page")) ((name . "reload") (format . "reload") (interactive . "U") (key-binding . "C-c C-r") (doc . "Reload the current page.")) ((name . "reload_ign_cache") (format . "reload_ign_cache") (interactive . "U") (doc . "Reload the current page, clearing the cache.")) ((name . "stop") (format . "stop") (interactive . "U") (key-binding . "C-c C-g") (doc . "Stop the currently loading page.")) ((name . "zoom_in") (format . "zoom_in") (interactive . "U") (key-binding . "C-c z i") (doc . "Increase the zoom level.")) ((name . "zoom_out") (format . "zoom_out") (interactive . "U") (key-binding . "C-c z o") (doc . "Decrease the zoom level.")) ((name . "toggle_zoom_type") (format . "toggle_zoom_type") (interactive) (doc . "Toggles the variable 'zoom_type' between 'full-content' and 'text-only' zoom. In 'text-only' zoom, only the text of the page is zoomed, while in 'full-content' zoom, images and other page elements are zoomed along with the text.")) ((name . "uri") (format . "uri
") (interactive . "U\nsAddress: ") (key-binding . "C-c C-o") (doc . "Visit the Uri ADDRESS")) ((name . "js") (format . "js ") (interactive . "U\nsJavascript to execute: ") (doc . "Execute JavaScript within the browser. * execute the javascript in BODY. * remember that the commands must not contain line breaks.")) ((name . "script") (format . "script ") (interactive . "U\nfJavascript file to execute: ") (key-binding . "C-c C-j") (doc . "execute the JavaScript in FILE.")) ((name . "toggle_status") (format . "toggle_status") (interactive . "U") (doc . "Toggle the display of the status bar.")) ((name . "spawn") (format . "spawn ") (interactive . "U\nFFile to spawn\nsAdditional arguments:") (doc . "Runs a command. * See the \"external scripts\" section of the Uzbl readme for details. * PATH is searched so giving the full path to commands is not necessary. * note that the arguments as specified in \"external scripts\" are appended at the end, so the argument numbers will be higher.")) ((name . "sync_spawn") (format . "sync_spawn ") (interactive . "U\nFFile to spawn\nsAdditional arguments:") (doc . "Tell Uzbl to synchronously spawn a command. See `ezbl-command-spawn' for details. * these are synchronous variants of spawn and sh, which means uzbl will wait for them to return. * you should only need to use these manually if you want to use a chain command in a handler that wants output from the command it runs")) ((name . "sh") (format . "sh ") (interactive . "U\nsCommand to execute: ") (doc . "Run a shell command. * runs a shell command by expanding %s in the shell_cmd variable with the specified command; primarily useful as a shortcut for \"spawn sh -c BODY\" * note that the arguments as specified in \"external scripts\" are appended at the end, so the argument numbers will be higher.")) ((name . "sync_sh") (format . "sync_sh ") (interactive . "U\nsCommand to run: ") (doc . "Tell Uzbl to synchronously run a shell command. See `ezbl-command-sh' for details. * these are synchronous variants of spawn and sh, which means uzbl will wait for them to return. * you should only need to use these manually if you want to use a chain command in a handler that wants output from the command it runs")) ((name . "talk_to_socket") (format . "talk_to_socket ") (doc . "Lets uzbl talk to a socketfile.")) ((name . "exit") (format . "exit") (interactive . "U") (key-binding . "C-c C-q") (doc . "Close this instance of Uzbl.")) ((name . "search") (format . "search ") (interactive . "U\nsSearch: ") (key-binding . "C-s") (doc . "Search for STRING within the content of the current Uzbl page. * search with no string will search for the next/previous occurrence of the string previously searched for.")) ((name . "search_reverse") (format . "search_reverse ") (interactive . "U\nsSearch backward: ") (key-binding . "C-r") (doc . "Search backwards for STRING in the current page. * search with no string will search for the next/previous occurrence of the string previously searched for.")) ((name . "search_clear") (format . "search_clear") (interactive . "U") (doc . "Unmark and clear the search string")) ((name . "dehilight") (format . "dehilight") (interactive) (doc . "Remove highlighting of search matches.")) ((name . "set") (format . "set = ") (interactive . (let* ((var-name (completing-read "Variable to set: " (mapcar '(lambda (item) (cdr-safe (assq 'name item))) ezbl-variables) nil ;; predicate t ;; require-match nil ;; initial-input 'ezbl-command-set-history)) ;; hist (default (ezbl-variable-get nil var-name)) (new-val (read-string (format "New value (%s): " default) nil nil default))) (list nil var-name new-val))) (key-binding . "C-c C-s") (doc . "Used for changing variables on the fly. Sets KEY equal to VALUE. * the changes are effective immediately; for example, setting the variable uri will make uzbl start loading, and changing status_format will make the status bar react immediately * if you want to unset a string, use `set' with one space as the value.")) ((name . "dump_config") (format . "dump_config") (doc . "Dump the current Uzbl configuration. * dumps your current config (which may have been changed at runtime) to stdout, in a format you can use to pipe into uzbl again (or use as config file)")) ((name . "dump_config_as_events") (format . "dump_config_as_events") (doc . "Dump the current config as a series of 'VARIABLE_SET' events, which can be handled by an event manager.")) ((name . "chain") (format . "chain ") (interactive . "U\nsCommand 1: \nsCommand 2: ") (doc . "Use for chaining multiple commands. * remember to quote the commands; one command must come as one parameter. * If you use chain with a handler script which must return some output (such as a cookie handler -- uzbl will wait for and use its output), use 'sync_spawn' or 'sync_sh' instead of 'spawn' or 'sh' in the command that should give the output.")) ((name . "print") (format . "print ") (doc . "Print the value of KEY. If KEY contains a string of the form '@var', the value of the Uzl variable 'var' is printed. * use this to print the value of a variable.")) ((name . "event") (format . "event
") (interactive . "U") (doc . "Send custom event. NAME is the event name and DETAILS is additional information to include.")) ((name . "request") (format . "request
") (interactive . "U") (doc . "Send custom request. Same idea as events, but to be processed by EM, not uzbl-core.")) ((name . "menu_add") (format . "menu_add