Commit 815cd46b authored by Link Mauve's avatar Link Mauve

Fix core completion, broken in the previous commit.

parent 86794bb0
......@@ -22,13 +22,13 @@ class CompletionCore:
def __init__(self, core):
self.core = core
def completion_help(self, the_input):
def help(self, the_input):
"""Completion for /help."""
commands = sorted(self.commands.keys()) + sorted(self.current_tab().commands.keys())
commands = sorted(self.core.commands.keys()) + sorted(self.core.current_tab().commands.keys())
return the_input.new_completion(commands, 1, quotify=False)
def completion_status(self, the_input):
def status(self, the_input):
"""
Completion of /status
"""
......@@ -36,7 +36,7 @@ class CompletionCore:
return the_input.new_completion([status for status in POSSIBLE_SHOW], 1, ' ', quotify=False)
def completion_presence(self, the_input):
def presence(self, the_input):
"""
Completion of /presence
"""
......@@ -47,35 +47,35 @@ class CompletionCore:
return the_input.auto_completion([status for status in POSSIBLE_SHOW], '', quotify=True)
def completion_theme(self, the_input):
def 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 = (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
return False
theme_files = [name[:-3] for name in names if name.endswith('.py') and name != '__init__.py']
if not 'default' in theme_files:
if 'default' not in theme_files:
theme_files.append('default')
return the_input.new_completion(theme_files, 1, '', quotify=False)
def completion_win(self, the_input):
def win(self, the_input):
"""Completion for /win"""
l = []
for tab in self.tabs:
for tab in self.core.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):
def join(self, the_input):
"""
Completion for /join
......@@ -98,9 +98,9 @@ class CompletionCore:
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):
relevant_rooms.extend(sorted(self.core.pending_invites.keys()))
bookmarks = {str(elem.jid): False for elem in self.core.bookmarks}
for tab in self.core.get_tabs(tabs.MucTab):
name = tab.name
if name in bookmarks and not tab.joined:
bookmarks[name] = True
......@@ -112,54 +112,54 @@ class CompletionCore:
if jid.user:
# we are writing the server: complete the server
serv_list = []
for tab in self.get_tabs(tabs.MucTab):
for tab in self.core.get_tabs(tabs.MucTab):
if tab.joined:
serv_list.append('%s@%s'% (jid.user, safeJID(tab.name).host))
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)
return the_input.new_completion(['/%s' % self.core.own_nick], 1, quotify=True)
else:
return the_input.new_completion(relevant_rooms, 1, quotify=True)
def completion_version(self, the_input):
def 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):
def list(self, the_input):
"""Completion for /list"""
muc_serv_list = []
for tab in self.get_tabs(tabs.MucTab): # TODO, also from an history
for tab in self.core.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):
def 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 = [tab.name for tab in self.core.tabs if tab]
nodes.remove('Roster')
return the_input.new_completion(nodes, 1, ' ', quotify=True)
def completion_runkey(self, the_input):
def runkey(self, the_input):
"""
Completion for /runkey
"""
list_ = []
list_.extend(self.key_func.keys())
list_.extend(self.current_tab().key_func.keys())
list_.extend(self.core.key_func.keys())
list_.extend(self.core.current_tab().key_func.keys())
return the_input.new_completion(list_, 1, quotify=False)
def completion_bookmark(self, the_input):
def bookmark(self, the_input):
"""Completion for /bookmark"""
args = common.shell_split(the_input.text)
n = the_input.get_argument_position(quoted=True)
......@@ -167,60 +167,60 @@ class CompletionCore:
if n == 2:
return the_input.new_completion(['true', 'false'], 2, quotify=True)
if n >= 3:
return
return False
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)
tab = self.core.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:
if default not in nicks:
nicks.append(default)
else:
if not nick in nicks:
if nick not 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 = [tab.name for tab in self.core.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):
def remove_bookmark(self, the_input):
"""Completion for /remove_bookmark"""
return the_input.new_completion([bm.jid for bm in self.bookmarks], 1, quotify=False)
return the_input.new_completion([bm.jid for bm in self.core.bookmarks], 1, quotify=False)
def completion_decline(self, the_input):
def 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)
return the_input.auto_completion(sorted(self.core.pending_invites.keys()), 1, '', quotify=True)
def completion_bind(self, the_input):
def 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('_')]
args = [key for key in self.core.key_func if not key.startswith('_')]
elif n == 2:
args = [key for key in self.key_func]
args = [key for key in self.core.key_func]
else:
return
return False
return the_input.new_completion(args, n, '', quotify=False)
def completion_message(self, the_input):
def message(self, the_input):
"""Completion for /message"""
n = the_input.get_argument_position(quoted=True)
if n >= 2:
return
return False
l = []
for jid in roster.jids():
if len(roster[jid]):
......@@ -230,7 +230,7 @@ class CompletionCore:
return the_input.new_completion(l, 1, '', quotify=True)
def completion_invite(self, the_input):
def invite(self, the_input):
"""Completion for /invite"""
n = the_input.get_argument_position(quoted=True)
if n == 1:
......@@ -242,14 +242,14 @@ class CompletionCore:
return the_input.new_completion(comp, n, quotify=True)
elif n == 2:
rooms = []
for tab in self.get_tabs(tabs.MucTab):
for tab in self.core.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):
def activity(self, the_input):
"""Completion for /activity"""
n = the_input.get_argument_position(quoted=True)
args = common.shell_split(the_input.text)
......@@ -263,34 +263,34 @@ class CompletionCore:
return the_input.new_completion(l, n, quotify=True)
def completion_mood(self, the_input):
def 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):
def last_activity(self, the_input):
"""
Completion for /last_activity <jid>
"""
n = the_input.get_argument_position(quoted=False)
if n >= 2:
return
return False
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):
def server_cycle(self, the_input):
"""Completion for /server_cycle"""
serv_list = set()
for tab in self.get_tabs(tabs.MucTab):
for tab in self.core.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):
def set(self, the_input):
"""Completion for /set"""
args = common.shell_split(the_input.text)
n = the_input.get_argument_position(quoted=True)
......@@ -299,9 +299,9 @@ class CompletionCore:
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]
if plugin_name not in self.core.plugin_manager.plugins:
return the_input.new_completion([], n, quotify=True)
plugin = self.core.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'))
......@@ -311,9 +311,9 @@ class CompletionCore:
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]
if plugin_name not in self.core.plugin_manager.plugins:
return the_input.new_completion([''], n, quotify=True)
plugin = self.core.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, {}))
......@@ -330,9 +330,9 @@ class CompletionCore:
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]
if plugin_name not in self.core.plugin_manager.plugins:
return the_input.new_completion([''], n, quotify=True)
plugin = self.core.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]):
......@@ -340,11 +340,11 @@ class CompletionCore:
else:
end_list = [str(config.get(args[2], '', args[1])), '']
else:
return
return False
return the_input.new_completion(end_list, n, quotify=True)
def completion_set_default(self, the_input):
def set_default(self, the_input):
""" Completion for /set_default
"""
args = common.shell_split(the_input.text)
......@@ -352,40 +352,40 @@ class CompletionCore:
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 []
return self.set(the_input)
return False
def completion_toggle(self, the_input):
def 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):
def 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
return False
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)
tab = self.core.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:
if default not in nicks:
nicks.append(default)
else:
if not nick in nicks:
if nick not 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 = [tab.name for tab in self.core.get_tabs(tabs.MucTab)]
muc_list.append('*')
return the_input.new_completion(muc_list, 1, quotify=True)
......@@ -42,7 +42,7 @@ from text_buffer import TextBuffer
from theming import get_theme
import keyboard
from . import completions
from . completions import CompletionCore
from . import commands
from . import handlers
from . structs import POSSIBLE_SHOW, DEPRECATED_ERRORS, \
......@@ -55,6 +55,7 @@ class Core(object):
"""
def __init__(self):
self.completion = CompletionCore(self)
# All uncaught exception are given to this callback, instead
# of being displayed on the screen and exiting the program.
sys.excepthook = self.on_exception
......@@ -1729,7 +1730,7 @@ class Core(object):
self.register_command('help', self.command_help,
usage='[command]',
shortdesc='\\_o< KOIN KOIN KOIN',
completion=self.completion_help)
completion=self.completion.help)
self.register_command('join', self.command_join,
usage="[room_name][@server][/nick] [password]",
desc="Join the specified room. You can specify a nickname "
......@@ -1744,7 +1745,7 @@ class Core(object):
"/join room2\n/join /me_again\n/join\n/join room@server"
".tld/my_nick password\n/join / password",
shortdesc='Join a room',
completion=self.completion_join)
completion=self.completion.join)
self.register_command('exit', self.command_quit,
desc='Just disconnect from the server and exit poezio.',
shortdesc='Exit poezio.')
......@@ -1758,7 +1759,7 @@ class Core(object):
self.register_command('win', self.command_win,
usage='<number or name>',
shortdesc='Go to the specified room',
completion=self.completion_win)
completion=self.completion.win)
self.commands['w'] = self.commands['win']
self.register_command('move_tab', self.command_move_tab,
usage='<source> <destination>',
......@@ -1769,7 +1770,7 @@ class Core(object):
"address. You can use \".\" as a shortcut for the current "
"tab.",
shortdesc='Move a tab.',
completion=self.completion_move_tab)
completion=self.completion.move_tab)
self.register_command('destroy_room', self.command_destroy_room,
usage='[room JID]',
desc='Try to destroy the room [room JID], or the current'
......@@ -1784,7 +1785,7 @@ class Core(object):
", chat, away, afk, dnd, busy, xa\" and the optional "
"[status message] argument will be your status message.",
shortdesc='Change your availability.',
completion=self.completion_status)
completion=self.completion.status)
self.commands['status'] = self.commands['show']
self.register_command('bookmark_local', self.command_bookmark_local,
usage="[roomname][/nick] [password]",
......@@ -1796,7 +1797,7 @@ class Core(object):
"with the nickname you\'re currently using in this room "
"(instead of default_nick)",
shortdesc='Bookmark a room locally.',
completion=self.completion_bookmark_local)
completion=self.completion.bookmark_local)
self.register_command('bookmark', self.command_bookmark,
usage="[roomname][/nick] [autojoin] [password]",
desc="Bookmark: Bookmark online the specified room (you "
......@@ -1807,7 +1808,7 @@ class Core(object):
" room will be bookmarked with the nickname you\'re "
"currently using in this room (instead of default_nick).",
shortdesc="Bookmark a room online.",
completion=self.completion_bookmark)
completion=self.completion.bookmark)
self.register_command('set', self.command_set,
usage="[plugin|][section] <option> [value]",
desc="Set the value of an option in your configuration file."
......@@ -1818,7 +1819,7 @@ class Core(object):
" with `/set mpd_client| host 127.0.0.1`. `toggle` can be "
"used as a special value to toggle a boolean option.",
shortdesc="Set the value of an option",
completion=self.completion_set)
completion=self.completion.set)
self.register_command('set_default', self.command_set_default,
usage="[section] <option>",
desc="Set the default value of an option. For example, "
......@@ -1826,48 +1827,48 @@ class Core(object):
"option. You can also reset options in specific "
"sections by doing `/set_default section option`.",
shortdesc="Set the default value of an option",
completion=self.completion_set_default)
completion=self.completion.set_default)
self.register_command('toggle', self.command_toggle,
usage='<option>',
desc='Shortcut for /set <option> toggle',
shortdesc='Toggle an option',
completion=self.completion_toggle)
completion=self.completion.toggle)
self.register_command('theme', self.command_theme,
usage='[theme name]',
desc="Reload the theme defined in the config file. If theme"
"_name is provided, set that theme before reloading it.",
shortdesc='Load a theme',
completion=self.completion_theme)
completion=self.completion.theme)
self.register_command('list', self.command_list,
usage='[server]',
desc="Get the list of public chatrooms"
" on the specified server.",
shortdesc='List the rooms.',
completion=self.completion_list)
completion=self.completion.list)
self.register_command('message', self.command_message,
usage='<jid> [optional message]',
desc="Open a conversation with the specified JID (even if it"
" is not in our roster), and send a message to it, if the "
"message is specified.",
shortdesc='Send a message',
completion=self.completion_message)
completion=self.completion.message)
self.register_command('version', self.command_version,
usage='<jid>',
desc="Get the software version of the given JID (usually its"
" XMPP client and Operating System).",
shortdesc='Get the software version of a JID.',
completion=self.completion_version)
completion=self.completion.version)
self.register_command('server_cycle', self.command_server_cycle,
usage='[domain] [message]',
desc='Disconnect and reconnect in all the rooms in domain.',
shortdesc='Cycle a range of rooms',
completion=self.completion_server_cycle)
completion=self.completion.server_cycle)
self.register_command('bind', self.command_bind,
usage='<key> <equ>',
desc="Bind a key to another key or to a “command”. For "
"example \"/bind ^H KEY_UP\" makes Control + h do the"
" same same as the Up key.",
completion=self.completion_bind,
completion=self.completion.bind,
shortdesc='Bind a key to another key.')
self.register_command('load', self.command_load,
usage='<plugin> [<otherplugin> …]',
......@@ -1884,7 +1885,7 @@ class Core(object):
desc="Send a directed presence to <JID> and using"
" [type] and [status] if provided.",
shortdesc='Send a directed presence.',
completion=self.completion_presence)
completion=self.completion.presence)
self.register_command('rawxml', self.command_rawxml,
usage='<xml>',
shortdesc='Send a custom xml stanza.')
......@@ -1892,7 +1893,7 @@ class Core(object):
usage='<jid> <room> [reason]',
desc='Invite jid in room with reason.',
shortdesc='Invite someone in a room.',
completion=self.completion_invite)
completion=self.completion.invite)
self.register_command('invitations', self.command_invitations,
shortdesc='Show the pending invitations.')
self.register_command('bookmarks', self.command_bookmarks,
......@@ -1902,20 +1903,20 @@ class Core(object):
desc="Remove the specified bookmark, or the "
"bookmark on the current tab, if any.",
shortdesc='Remove a bookmark',
completion=self.completion_remove_bookmark)
completion=self.completion.remove_bookmark)
self.register_command('xml_tab', self.command_xml_tab,
shortdesc='Open an XML tab.')
self.register_command('runkey', self.command_runkey,
usage='<key>',
shortdesc='Execute the action defined for <key>.',
completion=self.completion_runkey)
completion=self.completion.runkey)
self.register_command('self', self.command_self,
shortdesc='Remind you of who you are.')
self.register_command('last_activity', self.command_last_activity,
usage='<jid>',
desc='Informs you of the last activity of a JID.',
shortdesc='Get the activity of someone.',
completion=self.completion_last_activity)
completion=self.completion.last_activity)
self.register_command('ad-hoc', self.command_adhoc,
usage='<jid>',
shortdesc='List available ad-hoc commands on the given jid')
......@@ -1930,7 +1931,7 @@ class Core(object):
'(use the completion). Nothing means '
'"stop broadcasting an activity".',
shortdesc='Send your activity.',
completion=self.completion_activity)
completion=self.completion.activity)
if config.get('enable_user_mood'):
self.register_command('mood', self.command_mood,
usage='[<mood> [text]]',
......@@ -1938,7 +1939,7 @@ class Core(object):
'(use the completion). Nothing means '
'"stop broadcasting a mood".',
shortdesc='Send your mood.',
completion=self.completion_mood)
completion=self.completion.mood)
if config.get('enable_user_gaming'):
self.register_command('gaming', self.command_gaming,
usage='[<game name> [server address]]',
......@@ -2048,30 +2049,6 @@ class Core(object):
command_adhoc = commands.command_adhoc
command_self = commands.command_self
command_reload = commands.command_reload
completion_help = completions.completion_help
completion_status = completions.completion_status
completion_presence = completions.completion_presence
completion_theme = completions.completion_theme
completion_win = completions.completion_win
completion_join = completions.completion_join
completion_version = completions.completion_version
completion_list = completions.completion_list
completion_move_tab = completions.completion_move_tab
completion_runkey = completions.completion_runkey
completion_bookmark = completions.completion_bookmark
completion_remove_bookmark = completions.completion_remove_bookmark
completion_decline = completions.completion_decline
completion_bind = completions.completion_bind
completion_message = completions.completion_message
completion_invite = completions.completion_invite
completion_activity = completions.completion_activity
completion_mood = completions.completion_mood
completion_last_activity = completions.completion_last_activity
completion_server_cycle = completions.completion_server_cycle
completion_set = completions.completion_set
completion_set_default = completions.completion_set_default
completion_toggle = completions.completion_toggle
completion_bookmark_local = completions.completion_bookmark_local