Skip to content

Instantly share code, notes, and snippets.

@FireyFly
Created June 19, 2012 21:41
Show Gist options
  • Save FireyFly/2956705 to your computer and use it in GitHub Desktop.
Save FireyFly/2956705 to your computer and use it in GitHub Desktop.
Luakit module to interact with "globals" options from the browser itself.
----------------------------------------------------------------
-- 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