From 86794bb0fd8043763dee9e7a1476496fc71e70e1 Mon Sep 17 00:00:00 2001
From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
Date: Thu, 31 Mar 2016 23:00:47 +0100
Subject: Split core completion into its own class.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This commit is non-functional, it only changes indentation to make
other changes more apparent, I’m sorry if you come from the future and
are bisecting, it was the only way to make it look proper. :(
---
 poezio/core/completions.py | 722 +++++++++++++++++++++++----------------------
 1 file changed, 363 insertions(+), 359 deletions(-)

diff --git a/poezio/core/completions.py b/poezio/core/completions.py
index 2f7b9e65..04764268 100644
--- a/poezio/core/completions.py
+++ b/poezio/core/completions.py
@@ -18,370 +18,374 @@ from roster import roster
 from . structs import POSSIBLE_SHOW
 
 
-def completion_help(self, the_input):
-    """Completion for /help."""
-    commands = sorted(self.commands.keys()) + sorted(self.current_tab().commands.keys())
-    return the_input.new_completion(commands, 1, quotify=False)
-
-
-def completion_status(self, the_input):
-    """
-    Completion of /status
-    """
-    if the_input.get_argument_position() == 1:
-        return the_input.new_completion([status for status in POSSIBLE_SHOW], 1, ' ', quotify=False)
-
-
-def completion_presence(self, the_input):
-    """
-    Completion of /presence
-    """
-    arg = the_input.get_argument_position()
-    if arg == 1:
-        return the_input.auto_completion([jid for jid in roster.jids()], '', quotify=True)
-    elif arg == 2:
-        return the_input.auto_completion([status for status in POSSIBLE_SHOW], '', quotify=True)
-
-
-def completion_theme(self, the_input):
-    """ Completion for /theme"""
-    themes_dir = config.get('themes_dir')
-    themes_dir = themes_dir or\
-    os.path.join(os.environ.get('XDG_DATA_HOME') or\
-                     os.path.join(os.environ.get('HOME'), '.local', 'share'),
-                 'poezio', 'themes')
-    themes_dir = os.path.expanduser(themes_dir)
-    try:
-        names = os.listdir(themes_dir)
-    except OSError as e:
-        log.error('Completion for /theme failed', exc_info=True)
-        return
-    theme_files = [name[:-3] for name in names if name.endswith('.py') and name != '__init__.py']
-    if not 'default' in theme_files:
-        theme_files.append('default')
-    return the_input.new_completion(theme_files, 1, '', quotify=False)
-
-
-def completion_win(self, the_input):
-    """Completion for /win"""
-    l = []
-    for tab in self.tabs:
-        l.extend(tab.matching_names())
-    l = [i[1] for i in l]
-    return the_input.new_completion(l, 1, '', quotify=False)
-
-
-def completion_join(self, the_input):
-    """
-    Completion for /join
-
-    Try to complete the MUC JID:
-        if only a resource is provided, complete with the default nick
-        if only a server is provided, complete with the rooms from the
-            disco#items of that server
-        if only a nodepart is provided, complete with the servers of the
-            current joined rooms
-    """
-    n = the_input.get_argument_position(quoted=True)
-    args = common.shell_split(the_input.text)
-    if n != 1:
-        # we are not on the 1st argument of the command line
-        return False
-    if len(args) == 1:
-        args.append('')
-    jid = safeJID(args[1])
-    if args[1].endswith('@') and not jid.user and not jid.server:
-        jid.user = args[1][:-1]
-
-    relevant_rooms = []
-    relevant_rooms.extend(sorted(self.pending_invites.keys()))
-    bookmarks = {str(elem.jid): False for elem in self.bookmarks}
-    for tab in self.get_tabs(tabs.MucTab):
-        name = tab.name
-        if name in bookmarks and not tab.joined:
-            bookmarks[name] = True
-    relevant_rooms.extend(sorted(room[0] for room in bookmarks.items() if room[1]))
-
-    if the_input.last_completion:
-        return the_input.new_completion([], 1, quotify=True)
-
-    if jid.user:
-        # we are writing the server: complete the server
-        serv_list = []
+class CompletionCore:
+    def __init__(self, core):
+        self.core = core
+
+    def completion_help(self, the_input):
+        """Completion for /help."""
+        commands = sorted(self.commands.keys()) + sorted(self.current_tab().commands.keys())
+        return the_input.new_completion(commands, 1, quotify=False)
+
+
+    def completion_status(self, the_input):
+        """
+        Completion of /status
+        """
+        if the_input.get_argument_position() == 1:
+            return the_input.new_completion([status for status in POSSIBLE_SHOW], 1, ' ', quotify=False)
+
+
+    def completion_presence(self, the_input):
+        """
+        Completion of /presence
+        """
+        arg = the_input.get_argument_position()
+        if arg == 1:
+            return the_input.auto_completion([jid for jid in roster.jids()], '', quotify=True)
+        elif arg == 2:
+            return the_input.auto_completion([status for status in POSSIBLE_SHOW], '', quotify=True)
+
+
+    def completion_theme(self, the_input):
+        """ Completion for /theme"""
+        themes_dir = config.get('themes_dir')
+        themes_dir = themes_dir or\
+        os.path.join(os.environ.get('XDG_DATA_HOME') or\
+                         os.path.join(os.environ.get('HOME'), '.local', 'share'),
+                     'poezio', 'themes')
+        themes_dir = os.path.expanduser(themes_dir)
+        try:
+            names = os.listdir(themes_dir)
+        except OSError as e:
+            log.error('Completion for /theme failed', exc_info=True)
+            return
+        theme_files = [name[:-3] for name in names if name.endswith('.py') and name != '__init__.py']
+        if not 'default' in theme_files:
+            theme_files.append('default')
+        return the_input.new_completion(theme_files, 1, '', quotify=False)
+
+
+    def completion_win(self, the_input):
+        """Completion for /win"""
+        l = []
+        for tab in self.tabs:
+            l.extend(tab.matching_names())
+        l = [i[1] for i in l]
+        return the_input.new_completion(l, 1, '', quotify=False)
+
+
+    def completion_join(self, the_input):
+        """
+        Completion for /join
+
+        Try to complete the MUC JID:
+            if only a resource is provided, complete with the default nick
+            if only a server is provided, complete with the rooms from the
+                disco#items of that server
+            if only a nodepart is provided, complete with the servers of the
+                current joined rooms
+        """
+        n = the_input.get_argument_position(quoted=True)
+        args = common.shell_split(the_input.text)
+        if n != 1:
+            # we are not on the 1st argument of the command line
+            return False
+        if len(args) == 1:
+            args.append('')
+        jid = safeJID(args[1])
+        if args[1].endswith('@') and not jid.user and not jid.server:
+            jid.user = args[1][:-1]
+
+        relevant_rooms = []
+        relevant_rooms.extend(sorted(self.pending_invites.keys()))
+        bookmarks = {str(elem.jid): False for elem in self.bookmarks}
         for tab in self.get_tabs(tabs.MucTab):
-            if tab.joined:
-                serv_list.append('%s@%s'% (jid.user, safeJID(tab.name).host))
-        serv_list.extend(relevant_rooms)
-        return the_input.new_completion(serv_list, 1, quotify=True)
-    elif args[1].startswith('/'):
-        # we completing only a resource
-        return the_input.new_completion(['/%s' % self.own_nick], 1, quotify=True)
-    else:
-        return the_input.new_completion(relevant_rooms, 1, quotify=True)
-
-
-def completion_version(self, the_input):
-    """Completion for /version"""
-    comp = reduce(lambda x, y: x + [i.jid for i in y], (roster[jid].resources for jid in roster.jids() if len(roster[jid])), [])
-    return the_input.new_completion(sorted(comp), 1, quotify=False)
-
-
-def completion_list(self, the_input):
-    """Completion for /list"""
-    muc_serv_list = []
-    for tab in self.get_tabs(tabs.MucTab):   # TODO, also from an history
-        if tab.name not in muc_serv_list:
-            muc_serv_list.append(safeJID(tab.name).server)
-    if muc_serv_list:
-        return the_input.new_completion(muc_serv_list, 1, quotify=False)
-
-
-def completion_move_tab(self, the_input):
-    """Completion for /move_tab"""
-    n = the_input.get_argument_position(quoted=True)
-    if n == 1:
-        nodes = [tab.name for tab in self.tabs if tab]
-        nodes.remove('Roster')
-        return the_input.new_completion(nodes, 1, ' ', quotify=True)
-
-
-def completion_runkey(self, the_input):
-    """
-    Completion for /runkey
-    """
-    list_ = []
-    list_.extend(self.key_func.keys())
-    list_.extend(self.current_tab().key_func.keys())
-    return the_input.new_completion(list_, 1, quotify=False)
-
-
-def completion_bookmark(self, the_input):
-    """Completion for /bookmark"""
-    args = common.shell_split(the_input.text)
-    n = the_input.get_argument_position(quoted=True)
-
-    if n == 2:
-        return the_input.new_completion(['true', 'false'], 2, quotify=True)
-    if n >= 3:
-        return
-
-    if len(args) == 1:
-        args.append('')
-    jid = safeJID(args[1])
-
-    if jid.server and (jid.resource or jid.full.endswith('/')):
-        tab = self.get_tab_by_name(jid.bare, tabs.MucTab)
-        nicks = [tab.own_nick] if tab else []
-        default = os.environ.get('USER') if os.environ.get('USER') else 'poezio'
-        nick = config.get('default_nick')
-        if not nick:
-            if not default in nicks:
-                nicks.append(default)
+            name = tab.name
+            if name in bookmarks and not tab.joined:
+                bookmarks[name] = True
+        relevant_rooms.extend(sorted(room[0] for room in bookmarks.items() if room[1]))
+
+        if the_input.last_completion:
+            return the_input.new_completion([], 1, quotify=True)
+
+        if jid.user:
+            # we are writing the server: complete the server
+            serv_list = []
+            for tab in self.get_tabs(tabs.MucTab):
+                if tab.joined:
+                    serv_list.append('%s@%s'% (jid.user, safeJID(tab.name).host))
+            serv_list.extend(relevant_rooms)
+            return the_input.new_completion(serv_list, 1, quotify=True)
+        elif args[1].startswith('/'):
+            # we completing only a resource
+            return the_input.new_completion(['/%s' % self.own_nick], 1, quotify=True)
         else:
-            if not nick in nicks:
-                nicks.append(nick)
-        jids_list = ['%s/%s' % (jid.bare, nick) for nick in nicks]
-        return the_input.new_completion(jids_list, 1, quotify=True)
-    muc_list = [tab.name for tab in self.get_tabs(tabs.MucTab)]
-    muc_list.sort()
-    muc_list.append('*')
-    return the_input.new_completion(muc_list, 1, quotify=True)
-
-
-def completion_remove_bookmark(self, the_input):
-    """Completion for /remove_bookmark"""
-    return the_input.new_completion([bm.jid for bm in self.bookmarks], 1, quotify=False)
-
-
-def completion_decline(self, the_input):
-    """Completion for /decline"""
-    n = the_input.get_argument_position(quoted=True)
-    if n == 1:
-        return the_input.auto_completion(sorted(self.pending_invites.keys()), 1, '', quotify=True)
-
-
-def completion_bind(self, the_input):
-    n = the_input.get_argument_position()
-    if n == 1:
-        args = [key for key in self.key_func if not key.startswith('_')]
-    elif n == 2:
-        args = [key for key in self.key_func]
-    else:
-        return
-
-    return the_input.new_completion(args, n, '', quotify=False)
-
-
-def completion_message(self, the_input):
-    """Completion for /message"""
-    n = the_input.get_argument_position(quoted=True)
-    if n >= 2:
-        return
-    l = []
-    for jid in roster.jids():
-        if len(roster[jid]):
-            l.append(jid)
-            for resource in roster[jid].resources:
-                l.append(resource.jid)
-    return the_input.new_completion(l, 1, '', quotify=True)
-
-
-def completion_invite(self, the_input):
-    """Completion for /invite"""
-    n = the_input.get_argument_position(quoted=True)
-    if n == 1:
+            return the_input.new_completion(relevant_rooms, 1, quotify=True)
+
+
+    def completion_version(self, the_input):
+        """Completion for /version"""
         comp = reduce(lambda x, y: x + [i.jid for i in y], (roster[jid].resources for jid in roster.jids() if len(roster[jid])), [])
-        comp = sorted(comp)
-        bares = sorted(roster[contact].bare_jid for contact in roster.jids() if len(roster[contact]))
-        off = sorted(jid for jid in roster.jids() if jid not in bares)
-        comp = comp + bares + off
-        return the_input.new_completion(comp, n, quotify=True)
-    elif n == 2:
-        rooms = []
-        for tab in self.get_tabs(tabs.MucTab):
-            if tab.joined:
-                rooms.append(tab.name)
-        rooms.sort()
-        return the_input.new_completion(rooms, n, '', quotify=True)
-
-
-def completion_activity(self, the_input):
-    """Completion for /activity"""
-    n = the_input.get_argument_position(quoted=True)
-    args = common.shell_split(the_input.text)
-    if n == 1:
-        return the_input.new_completion(sorted(pep.ACTIVITIES.keys()), n, quotify=True)
-    elif n == 2:
-        if args[1] in pep.ACTIVITIES:
-            l = list(pep.ACTIVITIES[args[1]])
-            l.remove('category')
-            l.sort()
-            return the_input.new_completion(l, n, quotify=True)
-
-
-def completion_mood(self, the_input):
-    """Completion for /mood"""
-    n = the_input.get_argument_position(quoted=True)
-    if n == 1:
-        return the_input.new_completion(sorted(pep.MOODS.keys()), 1, quotify=True)
-
-
-def completion_last_activity(self, the_input):
-    """
-    Completion for /last_activity <jid>
-    """
-    n = the_input.get_argument_position(quoted=False)
-    if n >= 2:
-        return
-    comp = reduce(lambda x, y: x + [i.jid for i in y], (roster[jid].resources for jid in roster.jids() if len(roster[jid])), [])
-    return the_input.new_completion(sorted(comp), 1, '', quotify=False)
-
-
-def completion_server_cycle(self, the_input):
-    """Completion for /server_cycle"""
-    serv_list = set()
-    for tab in self.get_tabs(tabs.MucTab):
-        serv = safeJID(tab.name).server
-        serv_list.add(serv)
-    return the_input.new_completion(sorted(serv_list), 1, ' ')
-
-
-def completion_set(self, the_input):
-    """Completion for /set"""
-    args = common.shell_split(the_input.text)
-    n = the_input.get_argument_position(quoted=True)
-    if n >= len(args):
-        args.append('')
-    if n == 1:
-        if '|' in args[1]:
-            plugin_name, section = args[1].split('|')[:2]
-            if not plugin_name in self.plugin_manager.plugins:
-                    return the_input.new_completion([], n, quotify=True)
-            plugin = self.plugin_manager.plugins[plugin_name]
-            end_list = ['%s|%s' % (plugin_name, section) for section in plugin.config.sections()]
-        else:
-            end_list = set(config.options('Poezio'))
-            end_list.update(config.default.get('Poezio', {}))
-            end_list = list(end_list)
-            end_list.sort()
-    elif n == 2:
-        if '|' in args[1]:
-            plugin_name, section = args[1].split('|')[:2]
-            if not plugin_name in self.plugin_manager.plugins:
-                    return the_input.new_completion([''], n, quotify=True)
-            plugin = self.plugin_manager.plugins[plugin_name]
-            end_list = set(plugin.config.options(section or plugin_name))
-            if plugin.config.default:
-                end_list.update(plugin.config.default.get(section or plugin_name, {}))
-            end_list = list(end_list)
-            end_list.sort()
-        elif not config.has_option('Poezio', args[1]):
-            if config.has_section(args[1]):
-                end_list = config.options(args[1])
-                end_list.append('')
+        return the_input.new_completion(sorted(comp), 1, quotify=False)
+
+
+    def completion_list(self, the_input):
+        """Completion for /list"""
+        muc_serv_list = []
+        for tab in self.get_tabs(tabs.MucTab):   # TODO, also from an history
+            if tab.name not in muc_serv_list:
+                muc_serv_list.append(safeJID(tab.name).server)
+        if muc_serv_list:
+            return the_input.new_completion(muc_serv_list, 1, quotify=False)
+
+
+    def completion_move_tab(self, the_input):
+        """Completion for /move_tab"""
+        n = the_input.get_argument_position(quoted=True)
+        if n == 1:
+            nodes = [tab.name for tab in self.tabs if tab]
+            nodes.remove('Roster')
+            return the_input.new_completion(nodes, 1, ' ', quotify=True)
+
+
+    def completion_runkey(self, the_input):
+        """
+        Completion for /runkey
+        """
+        list_ = []
+        list_.extend(self.key_func.keys())
+        list_.extend(self.current_tab().key_func.keys())
+        return the_input.new_completion(list_, 1, quotify=False)
+
+
+    def completion_bookmark(self, the_input):
+        """Completion for /bookmark"""
+        args = common.shell_split(the_input.text)
+        n = the_input.get_argument_position(quoted=True)
+
+        if n == 2:
+            return the_input.new_completion(['true', 'false'], 2, quotify=True)
+        if n >= 3:
+            return
+
+        if len(args) == 1:
+            args.append('')
+        jid = safeJID(args[1])
+
+        if jid.server and (jid.resource or jid.full.endswith('/')):
+            tab = self.get_tab_by_name(jid.bare, tabs.MucTab)
+            nicks = [tab.own_nick] if tab else []
+            default = os.environ.get('USER') if os.environ.get('USER') else 'poezio'
+            nick = config.get('default_nick')
+            if not nick:
+                if not default in nicks:
+                    nicks.append(default)
             else:
-                end_list = []
-        else:
-            end_list = [str(config.get(args[1], '')), '']
-    elif n == 3:
-        if '|' in args[1]:
-            plugin_name, section = args[1].split('|')[:2]
-            if not plugin_name in self.plugin_manager.plugins:
-                    return the_input.new_completion([''], n, quotify=True)
-            plugin = self.plugin_manager.plugins[plugin_name]
-            end_list = [str(plugin.config.get(args[2], '', section or plugin_name)), '']
+                if not nick in nicks:
+                    nicks.append(nick)
+            jids_list = ['%s/%s' % (jid.bare, nick) for nick in nicks]
+            return the_input.new_completion(jids_list, 1, quotify=True)
+        muc_list = [tab.name for tab in self.get_tabs(tabs.MucTab)]
+        muc_list.sort()
+        muc_list.append('*')
+        return the_input.new_completion(muc_list, 1, quotify=True)
+
+
+    def completion_remove_bookmark(self, the_input):
+        """Completion for /remove_bookmark"""
+        return the_input.new_completion([bm.jid for bm in self.bookmarks], 1, quotify=False)
+
+
+    def completion_decline(self, the_input):
+        """Completion for /decline"""
+        n = the_input.get_argument_position(quoted=True)
+        if n == 1:
+            return the_input.auto_completion(sorted(self.pending_invites.keys()), 1, '', quotify=True)
+
+
+    def completion_bind(self, the_input):
+        n = the_input.get_argument_position()
+        if n == 1:
+            args = [key for key in self.key_func if not key.startswith('_')]
+        elif n == 2:
+            args = [key for key in self.key_func]
         else:
-            if not config.has_section(args[1]):
-                end_list = ['']
+            return
+
+        return the_input.new_completion(args, n, '', quotify=False)
+
+
+    def completion_message(self, the_input):
+        """Completion for /message"""
+        n = the_input.get_argument_position(quoted=True)
+        if n >= 2:
+            return
+        l = []
+        for jid in roster.jids():
+            if len(roster[jid]):
+                l.append(jid)
+                for resource in roster[jid].resources:
+                    l.append(resource.jid)
+        return the_input.new_completion(l, 1, '', quotify=True)
+
+
+    def completion_invite(self, the_input):
+        """Completion for /invite"""
+        n = the_input.get_argument_position(quoted=True)
+        if n == 1:
+            comp = reduce(lambda x, y: x + [i.jid for i in y], (roster[jid].resources for jid in roster.jids() if len(roster[jid])), [])
+            comp = sorted(comp)
+            bares = sorted(roster[contact].bare_jid for contact in roster.jids() if len(roster[contact]))
+            off = sorted(jid for jid in roster.jids() if jid not in bares)
+            comp = comp + bares + off
+            return the_input.new_completion(comp, n, quotify=True)
+        elif n == 2:
+            rooms = []
+            for tab in self.get_tabs(tabs.MucTab):
+                if tab.joined:
+                    rooms.append(tab.name)
+            rooms.sort()
+            return the_input.new_completion(rooms, n, '', quotify=True)
+
+
+    def completion_activity(self, the_input):
+        """Completion for /activity"""
+        n = the_input.get_argument_position(quoted=True)
+        args = common.shell_split(the_input.text)
+        if n == 1:
+            return the_input.new_completion(sorted(pep.ACTIVITIES.keys()), n, quotify=True)
+        elif n == 2:
+            if args[1] in pep.ACTIVITIES:
+                l = list(pep.ACTIVITIES[args[1]])
+                l.remove('category')
+                l.sort()
+                return the_input.new_completion(l, n, quotify=True)
+
+
+    def completion_mood(self, the_input):
+        """Completion for /mood"""
+        n = the_input.get_argument_position(quoted=True)
+        if n == 1:
+            return the_input.new_completion(sorted(pep.MOODS.keys()), 1, quotify=True)
+
+
+    def completion_last_activity(self, the_input):
+        """
+        Completion for /last_activity <jid>
+        """
+        n = the_input.get_argument_position(quoted=False)
+        if n >= 2:
+            return
+        comp = reduce(lambda x, y: x + [i.jid for i in y], (roster[jid].resources for jid in roster.jids() if len(roster[jid])), [])
+        return the_input.new_completion(sorted(comp), 1, '', quotify=False)
+
+
+    def completion_server_cycle(self, the_input):
+        """Completion for /server_cycle"""
+        serv_list = set()
+        for tab in self.get_tabs(tabs.MucTab):
+            serv = safeJID(tab.name).server
+            serv_list.add(serv)
+        return the_input.new_completion(sorted(serv_list), 1, ' ')
+
+
+    def completion_set(self, the_input):
+        """Completion for /set"""
+        args = common.shell_split(the_input.text)
+        n = the_input.get_argument_position(quoted=True)
+        if n >= len(args):
+            args.append('')
+        if n == 1:
+            if '|' in args[1]:
+                plugin_name, section = args[1].split('|')[:2]
+                if not plugin_name in self.plugin_manager.plugins:
+                        return the_input.new_completion([], n, quotify=True)
+                plugin = self.plugin_manager.plugins[plugin_name]
+                end_list = ['%s|%s' % (plugin_name, section) for section in plugin.config.sections()]
             else:
-                end_list = [str(config.get(args[2], '', args[1])), '']
-    else:
-        return
-    return the_input.new_completion(end_list, n, quotify=True)
-
-
-def completion_set_default(self, the_input):
-    """ Completion for /set_default
-    """
-    args = common.shell_split(the_input.text)
-    n = the_input.get_argument_position(quoted=True)
-    if n >= len(args):
-        args.append('')
-    if n == 1 or (n == 2 and config.has_section(args[1])):
-        return self.completion_set(the_input)
-    return []
-
-
-def completion_toggle(self, the_input):
-    "Completion for /toggle"
-    return the_input.new_completion(config.options('Poezio'), 1, quotify=False)
-
-
-def completion_bookmark_local(self, the_input):
-    """Completion for /bookmark_local"""
-    n = the_input.get_argument_position(quoted=True)
-    args = common.shell_split(the_input.text)
-
-    if n >= 2:
-        return
-    if len(args) == 1:
-        args.append('')
-    jid = safeJID(args[1])
-
-    if jid.server and (jid.resource or jid.full.endswith('/')):
-        tab = self.get_tab_by_name(jid.bare, tabs.MucTab)
-        nicks = [tab.own_nick] if tab else []
-        default = os.environ.get('USER') if os.environ.get('USER') else 'poezio'
-        nick = config.get('default_nick')
-        if not nick:
-            if not default in nicks:
-                nicks.append(default)
+                end_list = set(config.options('Poezio'))
+                end_list.update(config.default.get('Poezio', {}))
+                end_list = list(end_list)
+                end_list.sort()
+        elif n == 2:
+            if '|' in args[1]:
+                plugin_name, section = args[1].split('|')[:2]
+                if not plugin_name in self.plugin_manager.plugins:
+                        return the_input.new_completion([''], n, quotify=True)
+                plugin = self.plugin_manager.plugins[plugin_name]
+                end_list = set(plugin.config.options(section or plugin_name))
+                if plugin.config.default:
+                    end_list.update(plugin.config.default.get(section or plugin_name, {}))
+                end_list = list(end_list)
+                end_list.sort()
+            elif not config.has_option('Poezio', args[1]):
+                if config.has_section(args[1]):
+                    end_list = config.options(args[1])
+                    end_list.append('')
+                else:
+                    end_list = []
+            else:
+                end_list = [str(config.get(args[1], '')), '']
+        elif n == 3:
+            if '|' in args[1]:
+                plugin_name, section = args[1].split('|')[:2]
+                if not plugin_name in self.plugin_manager.plugins:
+                        return the_input.new_completion([''], n, quotify=True)
+                plugin = self.plugin_manager.plugins[plugin_name]
+                end_list = [str(plugin.config.get(args[2], '', section or plugin_name)), '']
+            else:
+                if not config.has_section(args[1]):
+                    end_list = ['']
+                else:
+                    end_list = [str(config.get(args[2], '', args[1])), '']
         else:
-            if not nick in nicks:
-                nicks.append(nick)
-        jids_list = ['%s/%s' % (jid.bare, nick) for nick in nicks]
-        return the_input.new_completion(jids_list, 1, quotify=True)
-    muc_list = [tab.name for tab in self.get_tabs(tabs.MucTab)]
-    muc_list.append('*')
-    return the_input.new_completion(muc_list, 1, quotify=True)
+            return
+        return the_input.new_completion(end_list, n, quotify=True)
+
+
+    def completion_set_default(self, the_input):
+        """ Completion for /set_default
+        """
+        args = common.shell_split(the_input.text)
+        n = the_input.get_argument_position(quoted=True)
+        if n >= len(args):
+            args.append('')
+        if n == 1 or (n == 2 and config.has_section(args[1])):
+            return self.completion_set(the_input)
+        return []
+
+
+    def completion_toggle(self, the_input):
+        "Completion for /toggle"
+        return the_input.new_completion(config.options('Poezio'), 1, quotify=False)
+
+
+    def completion_bookmark_local(self, the_input):
+        """Completion for /bookmark_local"""
+        n = the_input.get_argument_position(quoted=True)
+        args = common.shell_split(the_input.text)
+
+        if n >= 2:
+            return
+        if len(args) == 1:
+            args.append('')
+        jid = safeJID(args[1])
+
+        if jid.server and (jid.resource or jid.full.endswith('/')):
+            tab = self.get_tab_by_name(jid.bare, tabs.MucTab)
+            nicks = [tab.own_nick] if tab else []
+            default = os.environ.get('USER') if os.environ.get('USER') else 'poezio'
+            nick = config.get('default_nick')
+            if not nick:
+                if not default in nicks:
+                    nicks.append(default)
+            else:
+                if not nick in nicks:
+                    nicks.append(nick)
+            jids_list = ['%s/%s' % (jid.bare, nick) for nick in nicks]
+            return the_input.new_completion(jids_list, 1, quotify=True)
+        muc_list = [tab.name for tab in self.get_tabs(tabs.MucTab)]
+        muc_list.append('*')
+        return the_input.new_completion(muc_list, 1, quotify=True)
 
-- 
cgit v1.2.3