<commit_before>--
-- fn - l -- toggle listener
--
-- hold down fn, even when on, or command is ignored (minimizes false positives in noisy
-- environments.)
--
local module, placeholder = {}, {}

local speech   = require("hs.speech")
local listener = speech.listener
local fnutils  = require("hs.fnutils")
local log      = require("hs.logger").new("mySpeech","warning")
local settings = require("hs.settings")
local eventtap = require("hs.eventtap")
local hotkey   = require("hs.hotkey")

local commands = {}
local title    = "Hammerspoon"
local listenerCallback = function(listenerObj, text)
    if eventtap.checkKeyboardModifiers().fn then
        if commands[text] then
            commands[text]()
        else
            log.wf("Unrecognized command '%s' received", theCommand)
        end
    else
        log.vf("FN not depressed -- ignoring command '%s'", theCommand)
    end
end

local updateCommands = function()
    if module.recognizer then
        local cmdList = {}
        for k,v in fnutils.sortByKeys(commands) do
            table.insert(cmdList, k)
        end
        module.recognizer:commands(cmdList)
    end
end

module.log = log
module.commands = commands

module.add = function(text, func)
    assert(type(text) == "string", "command must be a string")
    assert(type(func) == "function", "action must be a function")

    if commands[text] then
        error("Command '"..text.."' is already registered", 2)
    end
    commands[text] = func

    updateCommands()
    return placeholder
end

module.remove = function(text)
    assert(type(text) == "string", "command must be a string")

    if commands[text] then
        commands[text] = nil
    else
        error("Command '"..text.."' is not registered", 2)
    end

    updateCommands()
    return placeholder
end

module.start = function()
    updateCommands() -- should be current, but just in case
    module.recognizer:title(title):start()
    settings.set("_asm.listener", true)
    return placeholder
end

module.stop = function()
    module.recognizer:title("Disabled: "..title):stop()
    return placeholder
end

module.isListening = function()
    if module.recognizer then
        return module.recognizer:isListening()
    else
        return nil
    end
end

module.disableCompletely = function()
    if module.recognizer then
        module.recognizer:delete()
    end
    module.recognizer = nil
    setmetatable(placeholder, nil)
    module.hotkey:disable()

    settings.set("_asm.listener", false)
end

module.init = function()
    if module.recognizer then
        error("Listener already initialized", 2)
    end
    module.recognizer = listener.new(title):setCallback(listenerCallback)
                                    :foregroundOnly(false)
                                    :blocksOtherRecognizers(false)

    module.hotkey = hotkey.bind({}, "l", function()
        if eventtap.checkKeyboardModifiers().fn then
            if module.isListening() then
                module.stop()
            else
                module.start()
            end
        else
            module.hotkey:disable()
            eventtap.keyStroke({}, "l")
            module.hotkey:enable()
        end
    end)

    return setmetatable(placeholder,  {
        __index = function(_, k)
            if module[k] then
                if type(module[k]) ~= "function" then return module[k] end
                return function(_, ...) return module[k](...) end
            else
                return nil
            end
        end,
        __tostring = function(_) return module.recognizer:title() end,
        __pairs = function(_) return pairs(module) end,
--         __gc = module.disableCompletely
    })
end<commit_msg>feedback for toggle<commit_after>--
-- fn - l -- toggle listener
--
-- hold down fn, even when on, or command is ignored (minimizes false positives in noisy
-- environments.)
--
local module, placeholder = {}, {}

local speech   = require("hs.speech")
local listener = speech.listener
local fnutils  = require("hs.fnutils")
local log      = require("hs.logger").new("mySpeech","warning")
local settings = require("hs.settings")
local eventtap = require("hs.eventtap")
local hotkey   = require("hs.hotkey")

local commands = {}
local title    = "Hammerspoon"
local listenerCallback = function(listenerObj, text)
    if eventtap.checkKeyboardModifiers().fn then
        if commands[text] then
            commands[text]()
        else
            log.wf("Unrecognized command '%s' received", text)
        end
    else
        log.vf("FN not depressed -- ignoring command '%s'", text)
    end
end

local updateCommands = function()
    if module.recognizer then
        local cmdList = {}
        for k,v in fnutils.sortByKeys(commands) do
            table.insert(cmdList, k)
        end
        module.recognizer:commands(cmdList)
    end
end

module.log = log
module.commands = commands

module.add = function(text, func)
    assert(type(text) == "string", "command must be a string")
    assert(type(func) == "function", "action must be a function")

    if commands[text] then
        error("Command '"..text.."' is already registered", 2)
    end
    commands[text] = func

    updateCommands()
    return placeholder
end

module.remove = function(text)
    assert(type(text) == "string", "command must be a string")

    if commands[text] then
        commands[text] = nil
    else
        error("Command '"..text.."' is not registered", 2)
    end

    updateCommands()
    return placeholder
end

module.start = function()
    updateCommands() -- should be current, but just in case
    module.recognizer:title(title):start()
    settings.set("_asm.listener", true)
    return placeholder
end

module.stop = function()
    module.recognizer:title("Disabled: "..title):stop()
    return placeholder
end

module.isListening = function()
    if module.recognizer then
        return module.recognizer:isListening()
    else
        return nil
    end
end

module.disableCompletely = function()
    if module.recognizer then
        module.recognizer:delete()
    end
    module.recognizer = nil
    setmetatable(placeholder, nil)
    module.hotkey:disable()
    module.listenLabel = module.listenLabel:delete()
    settings.set("_asm.listener", false)
end

module.init = function()
    if module.recognizer then
        error("Listener already initialized", 2)
    end
    module.recognizer = listener.new(title):setCallback(listenerCallback)
                                    :foregroundOnly(false)
                                    :blocksOtherRecognizers(false)

    module.hotkey = hotkey.bind({}, "l", function()
        if eventtap.checkKeyboardModifiers().fn then
            if module.isListening() then
                module.listenLabel = module.listenLabel:delete()
                module.stop()
            else
                local screen = require("hs.screen").primaryScreen():fullFrame()
                module.listenLabel = require("hs.drawing").text({
                                                x = screen.x + 5, y = screen.y + screen.h - 21,
                                                h = 14, w = 150
                                            }, require("hs.styledtext").new("Hammerspoon Listening...", {
                                                font = { name = "Menlo-Italic", size = 10 },
                                                color = { list = "Crayons", name = "Sky" },
                                                paragraphStyle = { lineBreak = "clip" }
                                            })):setBehaviorByLabels{"canJoinAllSpaces"}
                                            :setLevel("popUpMenu")
                                            :show()
                module.start()
            end
        else
            module.hotkey:disable()
            eventtap.keyStroke({}, "l")
            module.hotkey:enable()
        end
    end)

    return setmetatable(placeholder,  {
        __index = function(_, k)
            if module[k] then
                if type(module[k]) ~= "function" then return module[k] end
                return function(_, ...) return module[k](...) end
            else
                return nil
            end
        end,
        __tostring = function(_) return module.recognizer:title() end,
        __pairs = function(_) return pairs(module) end,
--         __gc = module.disableCompletely
    })
end
{'fraction_non_alphanumeric': 0.11062314540059347, 'fraction_numerical': 0.0018991097922848666, 'mean_word_length': 2.068463219227968, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3900432', 'n_tokens_mistral': 2270, 'n_tokens_neox': 2210, 'n_words': 605}