File: mode.lua

package info (click to toggle)
luakit 2012.09.13-r1-8
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 1,160 kB
  • ctags: 1,276
  • sloc: ansic: 6,086; makefile: 153; ruby: 79; sh: 38
file content (62 lines) | stat: -rw-r--r-- 2,090 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
---------------------------------------------------------------------------
-- @author Mason Larobina <mason.larobina@gmail.com>
-- @copyright 2010 Mason Larobina
---------------------------------------------------------------------------

--- Grab environment we need
local setmetatable = setmetatable
local type = type
local error = error

--- Mode setting and getting operations for objects.
module("lousy.mode")

--- The default mode if no default modes are set.
local default_mode = "normal"

--- Weak table of objects current modes.
local current_modes = {}
setmetatable(current_modes, { __mode = "k" })

--- Weak table of objects default modes.
local default_modes = {}
setmetatable(default_modes, { __mode = "k" })

--- Check if the mode can be set on an object.
-- An object is considered mode-able if it has an "emit_signal" method.
-- @param object The object to check.
function is_modeable(object)
    local t = type(object)
    return ((t == "table" or t == "userdata" or t == "lightuserdata")
        and type(object.emit_signal) == "function")
end

--- Get the current mode for a given object.
-- @param object A mode-able object.
-- @return The current mode of the given object, or the default mode of that object,
-- or "normal".
function get(object)
    if not is_modeable(object) then
        return error("attempt to get mode on non-modeable object")
    end
    return current_modes[object] or default_modes[object] or default_mode
end

--- Set the mode for a given object.
-- @param object A mode-able object.
-- @param mode A mode name (I.e. "insert", "command", ...)
-- @return The newly set mode.
function set(object, mode, ...)
    if not is_modeable(object) then
        return error("attempt to set mode on non-modeable object")
    end
    local mode = mode or default_modes[object] or default_mode
    current_modes[object] = mode
    -- Raises a mode change signal on the object.
    object:emit_signal("mode-changed", mode, ...)
    return mode
end

setmetatable(_M, { __call = function(_, ...) return set(...) end })

-- vim: et:sw=4:ts=8:sts=4:tw=80