def run(debug=False):
    d = dmenu()
    if debug:
        d.debug = True
    cache = d.cache_load()
    out = d.menu(cache,'Open:').strip()
    if len(out) > 0:
        if debug:
            print("Menu closed with user input: " + out)
        # Check if the action relates to a plugin
        plugins = load_plugins(debug)
        plugin_hook = False
        for plugin in plugins:
            if hasattr(plugin['plugin'], 'is_submenu') and plugin['plugin'].is_submenu == True:
                pluginTitle = d.prefs['indicator_submenu'] + ' ' + plugin['plugin'].title.strip()
            else:
                pluginTitle = plugin['plugin'].title.strip()

            if out[:len(pluginTitle)] == pluginTitle:
                plugin_hook = plugin["plugin"]

        # Check for plugin call
        if plugin_hook != False:
            plugin_hook.run(out[len(pluginTitle):])
            if d.debug:
                print("This command refers to a plugin")
        else:
            if d.debug:
                print("This command is not related to a plugin")
            # Check to see if the command begins with the alias indicator
            if out[0:len(d.prefs['indicator_alias'])] == d.prefs['indicator_alias']:
                out = d.retrieve_aliased_command(out)
                if d.debug:
                    print("An aliased command was called")
                    print("The command was swapped out for: " + str(out))
            else:
                # Check for store modifications
                # Dont allow command aliases that add new commands
                if out[0] in "+-":
                    action = out[0]
                    out = out[1:]
                    aliased = False
                    # Check for aliased command
                    if out.find(d.prefs['indicator_alias']) != -1 and action == '+':
                        aliased = True
                        tmp = out.split(d.prefs['indicator_alias'])
                        # out = [tmp[1].lstrip(), tmp[0].rstrip()]

                        command = tmp[0].rstrip()
                        if command is not '':
                            out = tmp[1].lstrip() + ' (' + command.replace(';', '') + ')'
                        else:
                            out = tmp[1].lstrip()

                        if len(out) == 0:
                            item = command
                        else:
                            item = [out, command]
                    elif out[:len(d.prefs['indicator_alias'])] == d.prefs['indicator_alias']:
                        item = out[len(d.prefs['indicator_alias']):].lstrip()
                        aliased = True
                    else:
                        item = out

                    found_in_store = False
                    for store_item in d.prefs['include_items']:
                        if d.debug:
                            print("is " + str(store_item) + " = " + str(item) + " ?")
                        if type(store_item) == list and out == store_item[0]:
                            found_in_store = True
                            break;
                        elif item == store_item:
                            found_in_store = True
                            break;

                    if action == '+' and found_in_store:
                        option = d.prefs['indicator_submenu'] + " Remove from store"
                        answer = d.menu("Item '" + str(item) + "' already in store\n"+option)
                        if answer != option:
                            sys.exit()
                        action = '-'
                    elif action == '-' and found_in_store == False:
                        option = d.prefs['indicator_submenu'] + " Add to store"
                        answer = d.menu("Item '" + (item) + "' was not found in store\n"+option)
                        if answer != option:
                            sys.exit()
                        action = '+'

                    if action == '+':
                        d.prefs['include_items'].append(item)
                        # Add the item to the alias lookup file
                        if aliased:
                            aliases = d.load_json(file_cache_aliasesLookup)
                            if item not in aliases:
                                aliases.append([
                                    d.prefs['indicator_alias'] + ' ' + item[0],
                                    item[1]
                                ])
                                d.save_json(file_cache_aliasesLookup, aliases)
                    elif action == '-':
                        if aliased:
                            to_remove = None
                            for include_item in d.prefs['include_items']:
                                if include_item[0] == out:
                                    to_remove = include_item
                            if to_remove is not None:
                                if d.debug:
                                    print("Item found and is")
                                    print(to_remove)
                                d.prefs['include_items'].remove(to_remove)
                            else:
                                if d.debug:
                                    print("Couldn't remove the item (item could not be located)")
                        else:
                            d.prefs['include_items'].remove(item)
                    else:
                        d.message_close()
                        d.menu("An error occured while servicing your request.\nYou may need to delete your configuration file.")
                        sys.exit()

                    d.save_preferences()

                    # Recreate the cache

                    cache_scanned = d.cache_open(file_cache)[:-1]

                    if cache_scanned == False:
                        d.cache_regenerate()
                        d.message_close()
                        sys.exit()
                    else:
                        cache_scanned = cache_scanned.split("\n")

                    if action == '+':
                        if d.debug:
                            print("Adding item to store: " + out)
                        d.message_open("Adding item to store: " + out)
                        if aliased:
                            cache_scanned = [d.prefs['indicator_alias'] + ' ' + out] + cache_scanned
                        else:
                            cache_scanned = [out] + cache_scanned
                        cache_scanned.sort(key=len)
                    else:
                        if aliased:
                            to_remove = d.prefs['indicator_alias'] + ' ' + out
                            if d.debug:
                                print("Removing item from store: " + to_remove)
                        else:
                            to_remove = out
                        d.message_open("Removing item from store: " + to_remove)
                        try:
                            cache_scanned.remove(to_remove)
                        except __HOLE__:
                            if d.debug:
                                print("Couldnt actually remove item from the cache")
                            else:
                                pass

                    d.cache_save(cache_scanned, file_cache)

                    d.message_close()
                    if action == '+':
                        if aliased == True:
                            message = "New item (" + command + " aliased as '" + out + "') added to cache."
                        else:
                            message = "New item (" + out + ") added to cache."
                    else:
                        message = "Existing item (" + out + ") removed from cache."

                    d.menu(message)
                    sys.exit()

            # Detect if the command is a web address and pass to handle_command
            if out[:7] == 'http://' or out[:8] == 'https://':
                handle_command(d, out)
            elif out.find(':') != -1:
                tmp = out.split(':')
                if len(tmp) != 2:
                    if d.debug:
                        print('Input command not understood')
                    sys.exit()
                else:
                    cmds = list(map(lambda x: x.strip(), tmp))

                run_withshell = False
                shell_hold = False
                if cmds[0][-1] == ';':
                    if cmds[0][-2] == ';':
                        shell_hold = True
                        if d.debug:
                            print('Will hold')
                    else:
                        if d.debug:
                            print('Wont hold')
                    cmds[0] = cmds[0].replace(';','')
                    run_withshell = True

                if cmds[0] == '':
                    items = list(filter(lambda x: x.find(cmds[1]) != -1, cache.split('\n')))
                    item = d.menu(items)
                    handle_command(d, item)
                elif cmds[0] in d.scan_binaries():
                    if d.debug:
                        print('Item[0] (' + cmds[0] + ') found in binaries')
                    # Get paths from cache
                    items = list(filter(lambda x: x.find('/') != -1, cache.split('\n')))
                    # If extension passed, filter by this
                    if cmds[1] != '':
                        items = list(filter(lambda x: x.find(cmds[1]) != -1, items))
                    filename = d.menu(items)
                    filename = os.path.expanduser(filename)
                    command = cmds[0] + " '" + filename + "'"
                    if run_withshell:
                        d.open_terminal(command, shell_hold)
                    else:
                        d.execute(command)
                elif cmds[0].find('/') != -1:
                    # Path came first, assume user wants of open it with a bin
                    if cmds[1] != '':
                        command = cmds[1] + " '" + os.path.expanduser(cmds[0]) + "'"
                    else:
                        binary = d.menu(d.scan_binaries())
                        command = binary + " '" + os.path.expanduser(cmds[0]) + "'"
                    d.execute(command)
                else:
                    d.menu(["Cant find " + cmds[0] + ", is it installed?"])
                    if d.debug:
                        print('Input command not understood')
                sys.exit()

            elif out == "rebuild cache":
                result = d.cache_regenerate()
                if result == 0:
                    d.menu(['Cache could not be saved'])
                elif result == 2:
                    d.menu(['Cache rebuilt','Performance issues were detected - some paths contained invalid characters'])
                else:
                    d.menu(['Success!'])

            else:
                handle_command(d, out)
dataset/ETHPy150Open markjones112358/dmenu-extended/dmenu_extended.py/run