def __init__(self, scriptName=None): self.menu_tree = list() self.handlers = list() self.menu_key_bindings = list() self.key_bindings = list() self.abbreviations = list() Parser.loadApplicationSettings()
def addHotKeysFromFile(self, filename): print("[Config] Parsing hotkeys config file: " + Parser.getShortFilePath(filename)) if not os.path.exists(filename) or not os.path.isfile(filename): print("Error! %s file are not exists!" % filename) return stopParsing = False addedActions = list() for line in open(filename, "r"): command = su.trimComments(line) if not command: continue if command == TOKEN.END: self.key_bindings.append("#IfWinActive") elif command.startswith('[') and command.endswith(']'): if Parser.gotIgnoreToken(command, addedActions, filename): break self.key_bindings.append("\n#IfWinActive " + Parser.getApp(command)) elif command.startswith(TOKEN.BIND): if len(command.split(' ', 3)) != 4: print("Error! failed to parse line: " + command) continue (bind_token, key, action, data) = command.split(' ', 3) self.setHotKeyAction(key, action, data) addedActions.append(action) else: print("[addHotKeysFromFile] Error: Failed to parse string: " + command)
def createPrintTextMenuFromFile(filename, builder): print("[Config] Parsing menu config file: " + Parser.getShortFilePath(filename)) if not os.path.exists(filename) or not os.path.isfile(filename): print("Error! %s file are not exists!" % filename) return menu = None deleteOnClick = False clipSave = True method = None import json data = json.loads(Parser.readFileAsString(filename)) if not len(data['MenuItems']): error("Invalid JSON file [%s] MenuItems dictionary is empty or invalid!" % filename) if data['MenuSettings'] and data['MenuSettings']['Hotkey']: hotKey = data['MenuSettings']['Hotkey'] menu = Menu(hotKey, hotKey, builder) else: error("Invalid JSON file [%s] MenuSettings.Hotkey value is not provided!" % filename) if data['MenuSettings']['clipSave'] == 'false': clipSave = False elif data['MenuSettings']['clipSave'] == 'true': clipSave = True if data['MenuSettings']['deleteOnClick'] == 'true': deleteOnClick = True elif data['MenuSettings']['deleteOnClick'] == 'false': deleteOnClick = False else: error("Invalid JSON file [%s] MenuSettings.deleteOnClick value is not provided!") if data['MenuSettings']['mode'] == 'print': method = menu.addPrintText elif data['MenuSettings']['mode'] == 'clipboard' or data['MenuSettings']['mode'] == 'paste': method = menu.addPasteText else: error("Invalid JSON file [%s] MenuSettings.mode value is not provided!") for key, subMenu in data['MenuItems'].iteritems(): if key == 'MenuSettings': continue if isinstance(subMenu, dict): for itemName, itemValue in subMenu.iteritems(): method(itemName, itemValue, subMenuName=key, deleteOnClick=deleteOnClick, clipSave=clipSave) menu.attachSubMenu(hotKey, key, key) if isinstance(subMenu, list): for item in subMenu: #If got empty json element ("",) - skip it if not item: continue itemName = item if len(item) > 80: itemName = item[:80] method(itemName, item, subMenuName=key, deleteOnClick=deleteOnClick, clipSave=clipSave) menu.attachSubMenu(hotKey, key, key) if menu: menu.assignMenuHotKey()
def hotKeyPrintText(self, key, text, pressEnter=False, useKeyDelay=True): Validator.notEmpty(text, "hotKeyPrintText on %s button" % Parser.parseHotKey(key)) self.key_bindings.append("\n%s::" % Parser.parseHotKey(key)) if useKeyDelay: self.key_bindings.append(setKeyDelay(text)) self.key_bindings.append("SendRaw "+ text) if pressEnter: self.key_bindings.append("Send {enter}") self.key_bindings.append("return")
def addAutoCompleteFromFile(self, filename): print("[Config] Parsing autocomplete config file: " + Parser.getShortFilePath(filename)) if not os.path.exists(filename) or not os.path.isfile(filename): print("Error! %s file are not exists!" % filename) return stopParsing = False applicationChosen = None autoCompleteAppData = None for line in open(filename, "r"): command = su.trimComments(line) if command: if command.startswith('[') and command.endswith( ']'): #Works only for selected application if Parser.gotIgnoreToken(command, autoCompleteAppData, filename): stopParsing = True if applicationChosen and len( autoCompleteAppData) or stopParsing: print("[addAutoCompleteForApp] writing %s entries" % len(autoCompleteAppData)) self.addAutoCompleteForApp( application=applicationChosen, data=autoCompleteAppData) if stopParsing: break if command == TOKEN.END: applicationChosen = None continue applicationChosen = Parser.getApp(command) autoCompleteAppData = dict() print("[addAutoCompleteForApp] Section for: " + applicationChosen) continue if applicationChosen: if '==' in command: keyAndCommand = command.split('==') if len(keyAndCommand) != 2: print("Error! failed to parse; " + command) continue autoCompleteAppData[ keyAndCommand[0]] = keyAndCommand[1] else: name = self.createTextAlias(command) if name: autoCompleteAppData[name] = command elif '==' in command: #Works in all applications keyAndCommand = command.split('==') if len(keyAndCommand) != 2: print("Error! failed to parse; " + command) continue status = self.addAutoComplete(keyAndCommand[0], keyAndCommand[1]) else: status = self.addAutoCompleteSmart(command)
def hotKeyPrintText(self, key, text, pressEnter=False, useKeyDelay=True): Validator.notEmpty( text, "hotKeyPrintText on %s button" % Parser.parseHotKey(key)) self.key_bindings.append("\n%s::" % Parser.parseHotKey(key)) if useKeyDelay: self.key_bindings.append(setKeyDelay(text)) self.key_bindings.append("SendRaw " + text) if pressEnter: self.key_bindings.append("Send {enter}") self.key_bindings.append("return")
def generate(): print("Generating AHK Script...") builder = ahk.ScriptBuilder() for file in getFilesByMask(ahk.config_dir, "hotkeys", ".txt"): builder.addHotKeysFromFile(file) for file in getFilesByMask(ahk.config_dir, "autocomplete", ".txt"): builder.addAutoCompleteFromFile(file) for file in menu_files: ahk.Menu.createPrintTextMenuFromFile(os.path.join(ahk.config_dir_name, file), builder) if os.path.exists("most_useful_autohotkey_scripts.py"): import most_useful_autohotkey_scripts as commons top_scripts = commons.CommonScripts(builder) if Parser.getCliArgument("--invert-wheel"): top_scripts.invertMouseScrollWheel() autocompl = commons.AutoComplete(builder, user_branches, user_remotes) autocompl.insertCurrentDate_Time() autocompl.insertCommonGitAliases() if os.path.exists("application_specific_bindings.py"): import application_specific_bindings as asp asp.generate(builder) builder.generateScript()
def generate(): print("Generating AHK Script...") builder = ahk.ScriptBuilder() for file in getFilesByMask(ahk.config_dir, "hotkeys", ".txt"): builder.addHotKeysFromFile(file) for file in getFilesByMask(ahk.config_dir, "autocomplete", ".txt"): builder.addAutoCompleteFromFile(file) for file in menu_files: ahk.Menu.createPrintTextMenuFromFile(os.path.join(ahk.config_dir_name, file), builder) if os.path.exists("most_useful_autohotkey_scripts.py"): import most_useful_autohotkey_scripts as commons top_scripts = commons.CommonScripts(builder) if Parser.getCliArgument('--invert-wheel'): top_scripts.invertMouseScrollWheel() autocompl = commons.AutoComplete(builder, user_branches, user_remotes) autocompl.insertCurrentDate_Time() autocompl.insertCommonGitAliases() if os.path.exists("application_specific_bindings.py"): import application_specific_bindings as asp asp.generate(builder) builder.generateScript()
def setHotKeyAction(self, key, action, data): if action == TOKEN.HK_PRINT: self.hotKeyPrintText(key, data, pressEnter=False, useKeyDelay=False) elif action == TOKEN.HK_PASTE: #TODO will be implemented later, adding stub now self.hotKeyPrintText(key, data, pressEnter=False, useKeyDelay=False) elif action == TOKEN.HK_WRAP: # output = data.replace(TOKEN.SELECTED_TEXT, action) #TODO create new implementation with unlimited usages of [SELECTION] if len(data.split(TOKEN.SELECTED_TEXT)) != 2: print("Split %s length !=2 when parsing line: %s" % (TOKEN.SELECTED_TEXT, data)) return (textLeft, textRight) = data.split(TOKEN.SELECTED_TEXT) self.hotKeyWrapSelectedText(key, textLeft, textRight, pressEnter=False) elif action == TOKEN.HK_INCLUDE_FILE: if not key == TOKEN.HK_DEFINED_IN_FILE: self.key_bindings.append("\n%s::" % Parser.parseHotKey(key)) self.key_bindings.append(includeFile(data))
def addAutoCompleteFromFile(self, filename): print("[Config] Parsing autocomplete config file: " + Parser.getShortFilePath(filename)) if not os.path.exists(filename) or not os.path.isfile(filename): print("Error! %s file are not exists!" % filename) return stopParsing = False applicationChosen = None autoCompleteAppData = None for line in open(filename, "r"): command = su.trimComments(line) if command: if command.startswith('[') and command.endswith(']'): #Works only for selected application if Parser.gotIgnoreToken(command, autoCompleteAppData, filename): stopParsing = True if applicationChosen and len(autoCompleteAppData) or stopParsing: print("[addAutoCompleteForApp] writing %s entries" % len(autoCompleteAppData)) self.addAutoCompleteForApp(application=applicationChosen, data=autoCompleteAppData) if stopParsing: break if command == TOKEN.END: applicationChosen = None continue applicationChosen = Parser.getApp(command) autoCompleteAppData = dict() print("[addAutoCompleteForApp] Section for: " + applicationChosen) continue if applicationChosen: if '==' in command: keyAndCommand = command.split('==') if len(keyAndCommand) != 2: print("Error! failed to parse; " + command) continue autoCompleteAppData[keyAndCommand[0]] = keyAndCommand[1] else: name = self.createTextAlias(command) if name: autoCompleteAppData[name] = command elif '==' in command: #Works in all applications keyAndCommand = command.split('==') if len(keyAndCommand) != 2: print("Error! failed to parse; " + command) continue status = self.addAutoComplete(keyAndCommand[0], keyAndCommand[1]) else: status = self.addAutoCompleteSmart(command)
def addPasteText(self, itemName, text, subMenuName=None, deleteOnClick=False, clipSave=True): Validator.notEmpty(text, "addPasteText for itemName %s " % itemName) itemName = Parser.filterMenuItemName(itemName) print("[PasteText] %s" % text) handler = self.createHandlerId() if not subMenuName: subMenuName=self.name self.builder.menu_tree.append("Menu, %s, Add, %s, %s" % (subMenuName, itemName, handler)) self.builder.handlers.append(handler + ":") self.pasteTextHandler(text, sendPaste=False, clipSave=False)
def hotKeyWrapSelectedText(self, key, textLeft, textRight, pressEnter=False): Validator.notEmpty( textLeft, "hotKeyWrapSelectedText <textLeft> on %s button" % Parser.parseHotKey(key)) Validator.notEmpty( textRight, "hotKeyWrapSelectedText <textRight> on %s button" % Parser.parseHotKey(key)) self.key_bindings.append("\n%s::" % Parser.parseHotKey(key)) self.key_bindings.append(""" ClipSaved := ClipboardAll Clipboard = Send ^x ClipWait 1 SendInput %s Send ^v SendInput %s Clipboard := ClipSaved ClipSaved = Return """ % (textLeft, textRight))
def hotKeyWrapSelectedText(self, key, textLeft, textRight, pressEnter=False): Validator.notEmpty(textLeft, "hotKeyWrapSelectedText <textLeft> on %s button" % Parser.parseHotKey(key)) Validator.notEmpty(textRight, "hotKeyWrapSelectedText <textRight> on %s button" % Parser.parseHotKey(key)) self.key_bindings.append("\n%s::" % Parser.parseHotKey(key)) self.key_bindings.append(""" ClipSaved := ClipboardAll Clipboard = Send ^x ClipWait 1 SendInput %s Send ^v SendInput %s Clipboard := ClipSaved ClipSaved = Return """ % (textLeft, textRight))
def addPasteText(self, itemName, text, subMenuName=None, deleteOnClick=False, clipSave=True): Validator.notEmpty(text, "addPasteText for itemName %s " % itemName) itemName = Parser.filterMenuItemName(itemName) print("[PasteText] %s" % text) handler = self.createHandlerId() if not subMenuName: subMenuName = self.name self.builder.menu_tree.append("Menu, %s, Add, %s, %s" % (subMenuName, itemName, handler)) self.builder.handlers.append(handler + ":") self.pasteTextHandler(text, sendPaste=False, clipSave=False)
def setHotKeyAction(self, key, action, data): if action == TOKEN.HK_PRINT: self.hotKeyPrintText(key, data, pressEnter=False, useKeyDelay=False) elif action == TOKEN.HK_PASTE: #TODO will be implemented later, adding stub now self.hotKeyPrintText(key, data, pressEnter=False, useKeyDelay=False) elif action == TOKEN.HK_WRAP: # output = data.replace(TOKEN.SELECTED_TEXT, action) #TODO create new implementation with unlimited usages of [SELECTION] if len(data.split(TOKEN.SELECTED_TEXT)) != 2: print("Split %s length !=2 when parsing line: %s" % (TOKEN.SELECTED_TEXT ,data)) return (textLeft, textRight) = data.split(TOKEN.SELECTED_TEXT) self.hotKeyWrapSelectedText(key, textLeft, textRight, pressEnter=False) elif action == TOKEN.HK_INCLUDE_FILE: if not key == TOKEN.HK_DEFINED_IN_FILE: self.key_bindings.append("\n%s::" % Parser.parseHotKey(key)) self.key_bindings.append(includeFile(data))
#Author: Artem Mamchych import ahkutils as ahk from utils.configfileparser import Parser if __name__ == "__main__": builder = ahk.ScriptBuilder() for file in Parser.getCliArgument('--menufiles='): ahk.script_file_name = file + ".ahk" ahk.Menu.createPrintTextMenuFromFile(file, builder) builder.generateScript()
def assignMenuHotKey(self): self.builder.menu_tree.append("return ; End of menu tree definition section.") self.builder.menu_key_bindings.append("%s::Menu, %s, Show ; i.e. press the Win-%s hotkey to show the menu.\n" % (Parser.parseHotKey(self.key), self.name, self.key))
def createPrintTextMenuFromFile(filename, builder): print("[Config] Parsing menu config file: " + Parser.getShortFilePath(filename)) if not os.path.exists(filename) or not os.path.isfile(filename): print("Error! %s file are not exists!" % filename) return menu = None deleteOnClick = False clipSave = True method = None import json data = json.loads(Parser.readFileAsString(filename)) if not len(data['MenuItems']): error( "Invalid JSON file [%s] MenuItems dictionary is empty or invalid!" % filename) if data['MenuSettings'] and data['MenuSettings']['Hotkey']: hotKey = data['MenuSettings']['Hotkey'] menu = Menu(hotKey, hotKey, builder) else: error( "Invalid JSON file [%s] MenuSettings.Hotkey value is not provided!" % filename) if data['MenuSettings']['clipSave'] == 'false': clipSave = False elif data['MenuSettings']['clipSave'] == 'true': clipSave = True if data['MenuSettings']['deleteOnClick'] == 'true': deleteOnClick = True elif data['MenuSettings']['deleteOnClick'] == 'false': deleteOnClick = False else: error( "Invalid JSON file [%s] MenuSettings.deleteOnClick value is not provided!" ) if data['MenuSettings']['mode'] == 'print': method = menu.addPrintText elif data['MenuSettings']['mode'] == 'clipboard' or data[ 'MenuSettings']['mode'] == 'paste': method = menu.addPasteText else: error( "Invalid JSON file [%s] MenuSettings.mode value is not provided!" ) for key, subMenu in data['MenuItems'].iteritems(): if key == 'MenuSettings': continue if isinstance(subMenu, dict): for itemName, itemValue in subMenu.iteritems(): method(itemName, itemValue, subMenuName=key, deleteOnClick=deleteOnClick, clipSave=clipSave) menu.attachSubMenu(hotKey, key, key) if isinstance(subMenu, list): for item in subMenu: #If got empty json element ("",) - skip it if not item: continue itemName = item if len(item) > 80: itemName = item[:80] method(itemName, item, subMenuName=key, deleteOnClick=deleteOnClick, clipSave=clipSave) menu.attachSubMenu(hotKey, key, key) if menu: menu.assignMenuHotKey()
def assignMenuHotKey(self): self.builder.menu_tree.append( "return ; End of menu tree definition section.") self.builder.menu_key_bindings.append( "%s::Menu, %s, Show ; i.e. press the Win-%s hotkey to show the menu.\n" % (Parser.parseHotKey(self.key), self.name, self.key))
# Author: Artem Mamchych import ahkutils as ahk from utils.configfileparser import Parser if __name__ == "__main__": builder = ahk.ScriptBuilder() for file in Parser.getCliArgument("--menufiles="): ahk.script_file_name = file + ".ahk" ahk.Menu.createPrintTextMenuFromFile(file, builder) builder.generateScript()
if Parser.getCliArgument("--invert-wheel"): top_scripts.invertMouseScrollWheel() autocompl = commons.AutoComplete(builder, user_branches, user_remotes) autocompl.insertCurrentDate_Time() autocompl.insertCommonGitAliases() if os.path.exists("application_specific_bindings.py"): import application_specific_bindings as asp asp.generate(builder) builder.generateScript() def getFilesByMask(directory, prefix, extension): files = list() os.chdir(directory) for file in os.listdir("."): if file.endswith(extension) and prefix in file: files.append(os.path.join(ahk.config_dir, file)) os.chdir(sys.path[0]) return files if __name__ == "__main__": # List type (--branches=master,develop,experimental) command line arguments are fetched here user_branches = Parser.getCliArgument("--branches=") user_remotes = Parser.getCliArgument("--remotes=") menu_files = Parser.getCliArgument("--menufiles=") generate()
if os.path.exists("most_useful_autohotkey_scripts.py"): import most_useful_autohotkey_scripts as commons top_scripts = commons.CommonScripts(builder) if Parser.getCliArgument('--invert-wheel'): top_scripts.invertMouseScrollWheel() autocompl = commons.AutoComplete(builder, user_branches, user_remotes) autocompl.insertCurrentDate_Time() autocompl.insertCommonGitAliases() if os.path.exists("application_specific_bindings.py"): import application_specific_bindings as asp asp.generate(builder) builder.generateScript() def getFilesByMask(directory, prefix, extension): files = list() os.chdir(directory) for file in os.listdir("."): if file.endswith(extension) and prefix in file: files.append(os.path.join(ahk.config_dir, file)) os.chdir(sys.path[0]) return files if __name__ == "__main__": #List type (--branches=master,develop,experimental) command line arguments are fetched here user_branches = Parser.getCliArgument('--branches=') user_remotes = Parser.getCliArgument('--remotes=') menu_files = Parser.getCliArgument('--menufiles=') generate()