Created
June 19, 2012 21:41
-
-
Save FireyFly/2956705 to your computer and use it in GitHub Desktop.
Luakit module to interact with "globals" options from the browser itself.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ---------------------------------------------------------------- | |
| -- Manages global options -- | |
| -- Copyright © 2012 Jonas Höglund <[email protected]> -- | |
| ---------------------------------------------------------------- | |
| -- Grab environment we need | |
| local string = string | |
| local type = type | |
| local pairs = pairs | |
| local assert = assert | |
| local lousy = require("lousy") | |
| local add_binds, add_cmds = add_binds, add_cmds | |
| local tostring = tostring | |
| local tonumber = tonumber | |
| -- For now, refer to them as options inside this file | |
| local options = globals | |
| module("options") | |
| ---- Helpers -------------------------------------------------------- | |
| -- Coerce a string into a boolean | |
| local function toboolean(str) | |
| if str == "true" then return true | |
| elseif str == "false" then return false | |
| else return nil | |
| end | |
| end | |
| -- Coerce a string into the given type. | |
| -- Returns nil if not successful. Supports at least string, number and boolean. | |
| local function coerce(str, ttype) | |
| if ttype == "string" then return str | |
| elseif ttype == "number" then return tonumber(str) | |
| elseif ttype == "boolean" then return toboolean(str) | |
| else return nil | |
| end | |
| end | |
| ---- Option-related functions --------------------------------------- | |
| -- is this option an accessor option? (an option which triggers an action when | |
| -- it's assigned to). | |
| local function opt_is_accessor(name) | |
| local opt = options[name] | |
| return type(opt) == "table" | |
| and type(opt.set) == "function" | |
| and opt.value ~= nil | |
| end | |
| -- gets the type of the given option | |
| local function opt_type(name) | |
| local opt = options[name] | |
| if opt_is_accessor(name) then | |
| return type(opt.value) | |
| else | |
| return type(opt) | |
| end | |
| end | |
| -- set the given option to the given value | |
| local function opt_set(name, value) | |
| local opt = options[name] | |
| if opt_is_accessor(name) then | |
| opt:set(value) | |
| else | |
| options[name] = value | |
| end | |
| end | |
| -- gets the value of the given option | |
| local function opt_get(name) | |
| local opt = options[name] | |
| if opt_is_accessor(name) then | |
| return opt.value | |
| else | |
| return opt | |
| end | |
| end | |
| ---- Commands ------------------------------------------------------- | |
| local cmd = lousy.bind.cmd | |
| add_cmds({ | |
| cmd("se[t]", "manage options", function (w, a) | |
| local function error_synopsis() | |
| w:error("use `:set <option>?`, `:set (no|)<option>` or `:set <option>=<value>`") | |
| end | |
| if not a then return error_synopsis() end | |
| -- Try various argument patterns | |
| local patterns = { query = "^([%w_]+)%?$", | |
| assign = "^([%w_]+)=(.*)$", | |
| assign_false = "^no([%w_]+)$", | |
| assign_true = "^([%w_]+)$" } | |
| local name, value, variant | |
| for key, pat in pairs(patterns) do | |
| name, value = string.match(a, pat) | |
| variant = key | |
| if name ~= nil then break end | |
| end | |
| -- no pattern matched; complain | |
| if name == nil then return error_synopsis() end | |
| -- turn boolean assignments (<option> or no<option>) into a regular one. | |
| if variant == "assign_true" or variant == "assign_false" then | |
| if opt_type(name) ~= "boolean" then | |
| if variant == "assign_true" then | |
| variant = "query" | |
| else | |
| w:error("Cannot set option to false; wrong type") | |
| return | |
| end | |
| else | |
| value = (variant == "assign_true") | |
| variant = "assign" | |
| end | |
| end | |
| -- Make sure that the option exists | |
| if options[name] == nil then | |
| w:error("No such option: " .. name) | |
| return | |
| end | |
| -- Handle the various types | |
| if variant == "query" then | |
| value = tostring(opt_get(name)) | |
| w:set_prompt(string.format("%s=%s", name, value)) | |
| elseif variant == "assign" then | |
| local ttype = opt_type(name) | |
| local val = coerce(value, ttype) | |
| if val == nil then | |
| w:error(string.format("Couldn't coerce new value into %s", ttype)) | |
| return | |
| else | |
| opt_set(name, val) | |
| end | |
| else | |
| assert(false, "`:set` shouldn't be able to reach this.") | |
| end | |
| end), | |
| }) | |
| -- vim: et:sw=4:ts=8:sts=4:tw=80 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment