local ADDON_NAME = ... -- Initialize saved variables local frame = CreateFrame("Frame") frame:RegisterEvent("ADDON_LOADED") frame:SetScript("OnEvent", function(self, event, addon) if addon ~= ADDON_NAME then return end KeybindSaverDaved = KeybindSaverDaved or {} KeybindSaverDaved.sets = KeybindSaverDaved.sets or {} end) ---@param setName string ---@return nil local function SaveKeybindSet(setName) if not setName or setName == "" then print("Set name cannot be empty") return end ---@type table local set = {} local numBindings = GetNumBindings() for i = 1, numBindings do local command, _, key1, key2 = GetBinding(i) if string.find(command, "CLICK ") then -- What a stupid fucking api, so fucking idiotic, retarded command, key2 = strsplit(":", command) end if key1 or key2 then set[command] = { key1 = key1, key2 = key2, } end end KeybindSaverDaved.sets[setName] = set print(string.format("Saved keybind set '%s'!", setName)) end ---@param command string ---@return nil local function UnbindCommand(command) if not command or command == "" then print("Cannot unbind an empty command") return end local keys = { GetBindingKey(command) } for _, key in ipairs(keys) do -- print("Unbinding", key) SetBinding(key) end end ---@param setName string ---@return nil local function RestoreKeybindSet(setName) if not setName or setName == "" then print("Set name cannot be empty") return end local set = KeybindSaverDaved.sets[setName] if not set then print(string.format("No set with the name '%s' exists", setName)) return end -- Clear all current bindings first ClearOverrideBindings(frame) -- Restore saved bindings for command, keys in pairs(set) do UnbindCommand(command) -- This fucking catastrophe binds a KEY(2) to CLICK A BUTTON (command) as a MOUSE BUTTON (key1) if string.find(command, "CLICK ") and keys.key2 then command = string.gsub(command, "CLICK ", "") local ok = SetBindingClick(keys.key2, command, keys.key1) if not ok then print("Failed to bind click", keys.key1, command) end else if keys.key1 then local ok = SetBinding(keys.key1, command) if not ok then print("Failed to bind", keys.key1, command) end end if keys.key2 then local ok = SetBinding(keys.key2, command) if not ok then print("Failed to bind", keys.key2, command) end end end end -- Save the changes SaveBindings(GetCurrentBindingSet()) SaveBindings(1) print(string.format("Restored keybind set '%s'", setName)) end ---@param setName string ---@return nil local function DeleteKeybindSet(setName) if not setName or setName == "" then print("Set name cannot be empty") return end if not KeybindSaverDaved.sets[setName] then print(string.format("No set with the name '%s' exists", setName)) return end KeybindSaverDaved.sets[setName] = nil print(string.format("Deleted keybind set '%s'", setName)) end ---@return nil local function ListKeybindSets() local sets = {} for setName in pairs(KeybindSaverDaved.sets) do table.insert(sets, setName) end table.sort(sets) if #sets == 0 then print("No keybind sets found") else print("Saved keybind sets:") print(table.concat(sets, ", ")) end end ---@param setName string ---@param importStr string ---@return nil local function ImportKeybindSet(setName, importStr) if not setName or setName == "" then print("Set name cannot be empty") return end local set = {} local lines = { strsplit("\n", importStr) } for _, line in ipairs(lines) do local command, key, key2 = strsplit(":", line) if command and key then if string.find(command, "CLICK ") then -- I can't believe we have to do this bullshit... local tmp = key key = key2 key2 = tmp end if not set[command] then set[command] = { key1 = key, key2 = key2, } end end end KeybindSaverDaved.sets[setName] = set print(string.format("Imported keybind set '%s'", setName)) end -- Create the import/export frame local importExportFrame = CreateFrame("Frame", "KBSImportExportFrame", UIParent) importExportFrame:SetSize(512, 512) importExportFrame:SetPoint("CENTER") importExportFrame:SetFrameStrata("HIGH") importExportFrame:EnableMouse(true) importExportFrame:SetMovable(true) importExportFrame:SetResizable(false) importExportFrame:SetBackdrop({ bgFile = "Interface/Tooltips/UI-Tooltip-Background", edgeFile = "Interface/Tooltips/UI-Tooltip-Border", tile = true, tileSize = 4, edgeSize = 4, insets = { left = 4, right = 4, top = 4, bottom = 4, }, }) importExportFrame:SetBackdropColor(0, 0, 0, 0.8) importExportFrame:SetBackdropBorderColor(0.5, 0.5, 0.5, 1) importExportFrame:SetMovable(true) importExportFrame:EnableMouse(true) importExportFrame:RegisterForDrag("LeftButton") importExportFrame:SetScript("OnDragStart", function(self) self:StartMoving() end) importExportFrame:SetScript("OnDragStop", function(self) self:StopMovingOrSizing() end) importExportFrame:SetScript("OnShow", function(self) self:SetScale(1) end) importExportFrame:Hide() local importingSet = nil local importExportFrameTextBox = CreateFrame("EditBox", "KBSImportExportFrameTextBox", importExportFrame) importExportFrameTextBox:SetSize(512, 512) importExportFrameTextBox:SetPoint("TOPLEFT", importExportFrame, "TOPLEFT", 0, 0) importExportFrameTextBox:SetFont("Fonts\\FRIZQT__.ttf", 12) importExportFrameTextBox:SetTextColor(1, 1, 1, 1) importExportFrameTextBox:SetTextInsets(20, 20, 20, 20) importExportFrameTextBox:SetMultiLine(true) importExportFrameTextBox:SetAutoFocus(true) importExportFrameTextBox:SetMaxLetters(1000000) importExportFrameTextBox:SetScript("OnEscapePressed", function(self) importExportFrame:Hide() if importingSet then local text = self:GetText() if text and text ~= "" then ImportKeybindSet(importingSet, text) end importingSet = nil end end) ---@param setName string ---@return nil local function ExportKeybindSet(setName) local set = KeybindSaverDaved.sets[setName] if not set then print(string.format("No set with the name '%s' exists", setName)) return end local export = {} for command, keys in pairs(set) do if command and keys and (keys.key1 or keys.key2) then local formatted = command if keys.key1 then formatted = formatted .. ":" .. keys.key1 end if keys.key2 then formatted = formatted .. ":" .. keys.key2 end export[#export + 1] = formatted end end table.sort(export) local exportStr = table.concat(export, "\n") importExportFrame:Show() importExportFrameTextBox:SetText(exportStr) importExportFrameTextBox:SetFocus() end ---@param setName string ---@return nil local function ImportKeybindSetDialogue(setName) if not setName or setName == "" then print("Set name cannot be empty") return end importingSet = setName importExportFrameTextBox:SetText("") importExportFrame:Show() importExportFrameTextBox:SetFocus() end ---@return nil local function PrintKeybindUsage() print("Keybind Saver Slash Commands:") print("/kbs save - Saves your current keybinds under the given ") print("/kbs restore - Restores the saved ") print("/kbs delete - Deletes the saved ") print("/kbs list - Lists all saved sets") print("/kbs export - Opens a window to export the given ") print("/kbs import - Opens a window to import a keybind set") end SLASH_KBS1 = "/kbs" SlashCmdList["KBS"] = function(argv) local args = { strsplit(" ", argv) } local cmd = args[1] if cmd == "save" then SaveKeybindSet(args[2]) end if cmd == "restore" then RestoreKeybindSet(args[2]) end if cmd == "delete" then DeleteKeybindSet(args[2]) end if cmd == "list" then ListKeybindSets() end if cmd == "export" then ExportKeybindSet(args[2]) end if cmd == "import" then ImportKeybindSetDialogue(args[2]) end if cmd == "" or not cmd then PrintKeybindUsage() end end