command completion. Also completion for command's arguments. (try it to complete the server of the muc with /join test@kiko[TAB] for example
This commit is contained in:
parent
c1a62ac897
commit
435bdd6e85
3 changed files with 168 additions and 85 deletions
84
src/core.py
84
src/core.py
|
@ -34,6 +34,8 @@ import common
|
|||
import theme
|
||||
import logging
|
||||
|
||||
from sleekxmpp.xmlstream.stanzabase import JID
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
import multiuserchat as muc
|
||||
|
@ -93,28 +95,33 @@ class Core(object):
|
|||
self.resize_timer = None
|
||||
self.previous_tab_nb = 0
|
||||
self.own_nick = config.get('own_nick', self.xmpp.boundjid.bare)
|
||||
# global commands, available from all tabs (having an input, of course)
|
||||
# global commands, available from all tabs
|
||||
# a command is tuple of the form:
|
||||
# (the function executing the command. Takes a string as argument,
|
||||
# a string representing the help message,
|
||||
# a completion function, taking a Input as argument. Can be None)
|
||||
# The completion function should return True if a completion was
|
||||
# made ; False otherwise
|
||||
self.commands = {
|
||||
'help': (self.command_help, '\_o< KOIN KOIN KOIN'),
|
||||
'join': (self.command_join, _("Usage: /join [room_name][@server][/nick] [password]\nJoin: Join the specified room. You can specify a nickname after a slash (/). If no nickname is specified, you will use the default_nick in the configuration file. You can omit the room name: you will then join the room you\'re looking at (useful if you were kicked). You can also provide a room_name without specifying a server, the server of the room you're currently in will be used. You can also provide a password to join the room.\nExamples:\n/join room@server.tld\n/join room@server.tld/John\n/join room2\n/join /me_again\n/join\n/join room@server.tld/my_nick password\n/join / password")),
|
||||
'quit': (self.command_quit, _("Usage: /quit\nQuit: Just disconnect from the server and exit poezio.")),
|
||||
'exit': (self.command_quit, _("Usage: /exit\nExit: Just disconnect from the server and exit poezio.")),
|
||||
'next': (self.rotate_rooms_right, _("Usage: /next\nNext: Go to the next room.")),
|
||||
'n': (self.rotate_rooms_right, _("Usage: /n\nN: Go to the next room.")),
|
||||
'prev': (self.rotate_rooms_left, _("Usage: /prev\nPrev: Go to the previous room.")),
|
||||
'p': (self.rotate_rooms_left, _("Usage: /p\nP: Go to the previous room.")),
|
||||
'win': (self.command_win, _("Usage: /win <number>\nWin: Go to the specified room.")),
|
||||
'w': (self.command_win, _("Usage: /w <number>\nW: Go to the specified room.")),
|
||||
'show': (self.command_show, _("Usage: /show <availability> [status]\nShow: Change your availability and (optionaly) your status. The <availability> argument is one of \"avail, available, ok, here, chat, away, afk, dnd, busy, xa\" and the optional [status] argument will be your status message")),
|
||||
'away': (self.command_away, _("Usage: /away [message]\nAway: Sets your availability to away and (optional) sets your status message. This is equivalent to '/show away [message]'")),
|
||||
'busy': (self.command_busy, _("Usage: /busy [message]\nBusy: Sets your availability to busy and (optional) sets your status message. This is equivalent to '/show busy [message]'")),
|
||||
'avail': (self.command_avail, _("Usage: /avail [message]\nAvail: Sets your availability to available and (optional) sets your status message. This is equivalent to '/show available [message]'")),
|
||||
'available': (self.command_avail, _("Usage: /available [message]\nAvailable: Sets your availability to available and (optional) sets your status message. This is equivalent to '/show available [message]'")),
|
||||
'bookmark': (self.command_bookmark, _("Usage: /bookmark [roomname][/nick]\nBookmark: Bookmark the specified room (you will then auto-join it on each poezio start). This commands uses the same syntaxe as /join. Type /help join for syntaxe examples. Note that when typing \"/bookmark\" on its own, the room will be bookmarked with the nickname you\'re currently using in this room (instead of default_nick)")),
|
||||
'set': (self.command_set, _("Usage: /set <option> [value]\nSet: Sets the value to the option in your configuration file. You can, for example, change your default nickname by doing `/set default_nick toto` or your resource with `/set resource blabla`. You can also set an empty value (nothing) by providing no [value] after <option>.")),
|
||||
'link': (self.command_link, _("Usage: /link [option] [number]\nLink: Interact with a link in the conversation. Available options are 'open', 'copy'. Open just opens the link in the browser if it's http://, Copy just copy the link in the clipboard. An optional number can be provided, it indicates which link to interact with.")),
|
||||
'whois': (self.command_whois, _('Usage: /whois <nickname>\nWhois: Request many informations about the user.')),
|
||||
'theme': (self.command_theme, _('Usage: /theme\nTheme: Reload the theme defined in the config file.')),
|
||||
'help': (self.command_help, '\_o< KOIN KOIN KOIN', None),
|
||||
'join': (self.command_join, _("Usage: /join [room_name][@server][/nick] [password]\nJoin: Join the specified room. You can specify a nickname after a slash (/). If no nickname is specified, you will use the default_nick in the configuration file. You can omit the room name: you will then join the room you\'re looking at (useful if you were kicked). You can also provide a room_name without specifying a server, the server of the room you're currently in will be used. You can also provide a password to join the room.\nExamples:\n/join room@server.tld\n/join room@server.tld/John\n/join room2\n/join /me_again\n/join\n/join room@server.tld/my_nick password\n/join / password"), self.completion_join),
|
||||
'exit': (self.command_quit, _("Usage: /exit\nExit: Just disconnect from the server and exit poezio."), None),
|
||||
'next': (self.rotate_rooms_right, _("Usage: /next\nNext: Go to the next room."), None),
|
||||
'n': (self.rotate_rooms_right, _("Usage: /n\nN: Go to the next room."), None),
|
||||
'prev': (self.rotate_rooms_left, _("Usage: /prev\nPrev: Go to the previous room."), None),
|
||||
'p': (self.rotate_rooms_left, _("Usage: /p\nP: Go to the previous room."), None),
|
||||
'win': (self.command_win, _("Usage: /win <number>\nWin: Go to the specified room."), None),
|
||||
'w': (self.command_win, _("Usage: /w <number>\nW: Go to the specified room."), None),
|
||||
'show': (self.command_show, _("Usage: /show <availability> [status]\nShow: Change your availability and (optionaly) your status. The <availability> argument is one of \"avail, available, ok, here, chat, away, afk, dnd, busy, xa\" and the optional [status] argument will be your status message"), None),
|
||||
'away': (self.command_away, _("Usage: /away [message]\nAway: Sets your availability to away and (optional) sets your status message. This is equivalent to '/show away [message]'"), None),
|
||||
'busy': (self.command_busy, _("Usage: /busy [message]\nBusy: Sets your availability to busy and (optional) sets your status message. This is equivalent to '/show busy [message]'"), None),
|
||||
'avail': (self.command_avail, _("Usage: /avail [message]\nAvail: Sets your availability to available and (optional) sets your status message. This is equivalent to '/show available [message]'"), None),
|
||||
'available': (self.command_avail, _("Usage: /available [message]\nAvailable: Sets your availability to available and (optional) sets your status message. This is equivalent to '/show available [message]'"), None),
|
||||
'bookmark': (self.command_bookmark, _("Usage: /bookmark [roomname][/nick]\nBookmark: Bookmark the specified room (you will then auto-join it on each poezio start). This commands uses the same syntaxe as /join. Type /help join for syntaxe examples. Note that when typing \"/bookmark\" on its own, the room will be bookmarked with the nickname you\'re currently using in this room (instead of default_nick)"), None),
|
||||
'set': (self.command_set, _("Usage: /set <option> [value]\nSet: Sets the value to the option in your configuration file. You can, for example, change your default nickname by doing `/set default_nick toto` or your resource with `/set resource blabla`. You can also set an empty value (nothing) by providing no [value] after <option>."), None),
|
||||
'link': (self.command_link, _("Usage: /link [option] [number]\nLink: Interact with a link in the conversation. Available options are 'open', 'copy'. Open just opens the link in the browser if it's http://, Copy just copy the link in the clipboard. An optional number can be provided, it indicates which link to interact with."), None),
|
||||
'whois': (self.command_whois, _('Usage: /whois <nickname>\nWhois: Request many informations about the user.'), None),
|
||||
'theme': (self.command_theme, _('Usage: /theme\nTheme: Reload the theme defined in the config file.'), None),
|
||||
}
|
||||
|
||||
self.key_func = {
|
||||
|
@ -146,7 +153,6 @@ class Core(object):
|
|||
self.xmpp.add_event_handler("roster_update", self.on_roster_update)
|
||||
self.xmpp.add_event_handler("changed_status", self.on_presence)
|
||||
|
||||
|
||||
def grow_information_win(self):
|
||||
"""
|
||||
"""
|
||||
|
@ -908,6 +914,28 @@ class Core(object):
|
|||
self.current_tab().on_gain_focus()
|
||||
self.refresh_window()
|
||||
|
||||
def completion_join(self, the_input):
|
||||
"""
|
||||
Try to complete the server of the MUC's jid (for now only from the currently
|
||||
open ones)
|
||||
TODO: have a history of recently joined MUCs, and use that too
|
||||
"""
|
||||
txt = the_input.get_text()
|
||||
if len(txt.split()) != 2:
|
||||
# we are not on the 1st argument of the command line
|
||||
return False
|
||||
jid = JID(txt.split()[1])
|
||||
if not jid.user or not jid.server or jid.resource != '':
|
||||
# we are not writing the server part of the jid
|
||||
return True
|
||||
serv = jid.server
|
||||
serv_list = []
|
||||
for tab in self.tabs:
|
||||
if isinstance(tab, MucTab):
|
||||
serv_list.append('%s@%s'% (jid.user, JID(tab.get_name()).host))
|
||||
the_input.auto_completion(serv_list, '')
|
||||
return True
|
||||
|
||||
def command_join(self, arg):
|
||||
"""
|
||||
/join [room][/nick] [password]
|
||||
|
@ -1211,21 +1239,9 @@ class Core(object):
|
|||
else:
|
||||
self.command_say(line)
|
||||
|
||||
# def command_say(self, line):
|
||||
# if isinstance(self.current_tab(), PrivateTab):
|
||||
# muc.send_private_message(self.xmpp, self.current_tab().get_name(), line)
|
||||
# elif isinstance(self.current_tab(), ConversationTab): # todo, special case # hu, I can't remember what special case was needed when I wrote that…
|
||||
# if isinstance(self.current_tab(), PrivateTab) or\
|
||||
# isinstance(self.current_tab(), ConversationTab):
|
||||
# self.add_message_to_text_buffer(self.current_tab().get_room(), line, None, self.own_nick)
|
||||
# elif isinstance(self.current_tab(), MucTab):
|
||||
# muc.send_groupchat_message(self.xmpp, self.current_tab().get_name(), line)
|
||||
# self.doupdate()
|
||||
|
||||
def doupdate(self):
|
||||
self.current_tab().just_before_refresh()
|
||||
curses.doupdate()
|
||||
|
||||
# # global core object
|
||||
core = Core(connection)
|
||||
|
||||
|
|
124
src/tab.py
124
src/tab.py
|
@ -59,11 +59,39 @@ class Tab(object):
|
|||
# and use them in on_input
|
||||
self.commands = {} # and their own commands
|
||||
|
||||
def refresh(self, tabs, informations, roster):
|
||||
def complete_commands(self, the_input):
|
||||
"""
|
||||
Called on each screen refresh (when something has changed)
|
||||
Does command completion on the specified input for both global and tab-specific
|
||||
commands.
|
||||
This should be called from the completion method (on tab, for example), passing
|
||||
the input where completion is to be made.
|
||||
It can completion the command name itself or an argument of the command.
|
||||
Returns True if a completion was made, False else.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
txt = the_input.get_text()
|
||||
# check if this is a command
|
||||
if txt.startswith('/') and not txt.startswith('//'):
|
||||
# check if we are in the middle of the command name
|
||||
if len(txt.split()) > 1 or\
|
||||
(txt.endswith(' ') and not the_input.last_completion):
|
||||
command_name = txt.split()[0][1:]
|
||||
if command_name in self.core.commands:
|
||||
command = self.core.commands[command_name]
|
||||
elif command_name in self.commands:
|
||||
command = self.commands[command_name]
|
||||
else: # Unknown command, cannot complete
|
||||
return False
|
||||
if command[2] is None:
|
||||
return False # There's no completion functio
|
||||
else:
|
||||
return command[2](the_input)
|
||||
else:
|
||||
# complete the command's name
|
||||
words = ['/%s'%(name) for name in list(self.core.commands.keys())] +\
|
||||
['/%s'% (name) for name in list(self.commands.keys())]
|
||||
the_input.auto_completion(words, '')
|
||||
return True
|
||||
return False
|
||||
|
||||
def resize(self):
|
||||
self.size = (self.height, self.width) = self.core.stdscr.getmaxyx()
|
||||
|
@ -72,6 +100,12 @@ class Tab(object):
|
|||
else:
|
||||
self.visible = True
|
||||
|
||||
def refresh(self, tabs, informations, roster):
|
||||
"""
|
||||
Called on each screen refresh (when something has changed)
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_color_state(self):
|
||||
"""
|
||||
returns the color that should be used in the GlobalInfoBar
|
||||
|
@ -224,7 +258,7 @@ class ChatTab(Tab):
|
|||
self.key_func['\n'] = self.on_enter
|
||||
self.commands['say'] = (self.command_say,
|
||||
_("""Usage: /say <message>\nSay: Just send the message.
|
||||
Useful if you want your message to begin with a '/'"""))
|
||||
Useful if you want your message to begin with a '/'"""), None)
|
||||
|
||||
def last_words_completion(self):
|
||||
"""
|
||||
|
@ -242,7 +276,7 @@ class ChatTab(Tab):
|
|||
for word in msg.txt.split():
|
||||
if len(word) >= 4 and word not in words:
|
||||
words.append(word)
|
||||
self.input.auto_completion(words, False)
|
||||
self.input.auto_completion(words, ' ')
|
||||
|
||||
def on_enter(self):
|
||||
txt = self.input.key_enter()
|
||||
|
@ -282,14 +316,14 @@ class MucTab(ChatTab):
|
|||
self.key_func['^I'] = self.completion
|
||||
self.key_func['M-i'] = self.completion
|
||||
# commands
|
||||
self.commands['ignore'] = (self.command_ignore, _("Usage: /ignore <nickname> \nIgnore: Ignore a specified nickname."))
|
||||
self.commands['unignore'] = (self.command_unignore, _("Usage: /unignore <nickname>\nUnignore: Remove the specified nickname from the ignore list."))
|
||||
self.commands['kick'] = (self.command_kick, _("Usage: /kick <nick> [reason]\nKick: Kick the user with the specified nickname. You also can give an optional reason."))
|
||||
self.commands['topic'] = (self.command_topic, _("Usage: /topic <subject>\nTopic: Change the subject of the room"))
|
||||
self.commands['query'] = (self.command_query, _('Usage: /query <nick> [message]\nQuery: Open a private conversation with <nick>. This nick has to be present in the room you\'re currently in. If you specified a message after the nickname, it will immediately be sent to this user'))
|
||||
self.commands['part'] = (self.command_part, _("Usage: /part [message]\n Part: disconnect from a room. You can specify an optional message."))
|
||||
self.commands['nick'] = (self.command_nick, _("Usage: /nick <nickname>\nNick: Change your nickname in the current room"))
|
||||
self.commands['recolor'] = (self.command_recolor, _('Usage: /recolor\nRecolor: Re-assign a color to all participants of the current room, based on the last time they talked. Use this if the participants currently talking have too many identical colors.'))
|
||||
self.commands['ignore'] = (self.command_ignore, _("Usage: /ignore <nickname> \nIgnore: Ignore a specified nickname."), None)
|
||||
self.commands['unignore'] = (self.command_unignore, _("Usage: /unignore <nickname>\nUnignore: Remove the specified nickname from the ignore list."), None)
|
||||
self.commands['kick'] = (self.command_kick, _("Usage: /kick <nick> [reason]\nKick: Kick the user with the specified nickname. You also can give an optional reason."), None)
|
||||
self.commands['topic'] = (self.command_topic, _("Usage: /topic <subject>\nTopic: Change the subject of the room"), None)
|
||||
self.commands['query'] = (self.command_query, _('Usage: /query <nick> [message]\nQuery: Open a private conversation with <nick>. This nick has to be present in the room you\'re currently in. If you specified a message after the nickname, it will immediately be sent to this user'), None)
|
||||
self.commands['part'] = (self.command_part, _("Usage: /part [message]\n Part: disconnect from a room. You can specify an optional message."), None)
|
||||
self.commands['nick'] = (self.command_nick, _("Usage: /nick <nickname>\nNick: Change your nickname in the current room"), None)
|
||||
self.commands['recolor'] = (self.command_recolor, _('Usage: /recolor\nRecolor: Re-assign a color to all participants of the current room, based on the last time they talked. Use this if the participants currently talking have too many identical colors.'), None)
|
||||
self.resize()
|
||||
|
||||
def command_recolor(self, arg):
|
||||
|
@ -478,8 +512,17 @@ class MucTab(ChatTab):
|
|||
"""
|
||||
Called when Tab is pressed, complete the nickname in the input
|
||||
"""
|
||||
if self.complete_commands(self.input):
|
||||
return
|
||||
compare_users = lambda x: x.last_talked
|
||||
self.input.auto_completion([user.nick for user in sorted(self._room.users, key=compare_users, reverse=True)])
|
||||
word_list = [user.nick for user in sorted(self._room.users, key=compare_users, reverse=True)]
|
||||
after = config.get('after_completion', ',')+" "
|
||||
if ' ' not in self.input.get_text() or (self.input.last_completion and\
|
||||
self.input.get_text()[:-len(after)] == self.input.last_completion):
|
||||
add_after = after
|
||||
else:
|
||||
add_after = ' '
|
||||
self.input.auto_completion(word_list, add_after)
|
||||
|
||||
def get_color_state(self):
|
||||
return self._room.color_state
|
||||
|
@ -531,10 +574,17 @@ class PrivateTab(ChatTab):
|
|||
self.info_win = windows.TextWin()
|
||||
self.tab_win = windows.GlobalInfoBar()
|
||||
self.input = windows.MessageInput()
|
||||
self.commands['unquery'] = (self.command_unquery, _("Usage: /unquery\nUnquery: close the tab"))
|
||||
self.commands['part'] = (self.command_unquery, _("Usage: /part\Part: close the tab"))
|
||||
# keys
|
||||
self.key_func['^I'] = self.completion
|
||||
self.key_func['M-i'] = self.completion
|
||||
# commands
|
||||
self.commands['unquery'] = (self.command_unquery, _("Usage: /unquery\nUnquery: close the tab"), None)
|
||||
self.commands['part'] = (self.command_unquery, _("Usage: /part\Part: close the tab"), None)
|
||||
self.resize()
|
||||
|
||||
def completion(self):
|
||||
self.complete_commands(self.input)
|
||||
|
||||
def command_say(self, line):
|
||||
muc.send_private_message(self.core.xmpp, self.get_name(), line)
|
||||
self.core.add_message_to_text_buffer(self.get_room(), line, None, self.get_room().own_nick)
|
||||
|
@ -631,6 +681,16 @@ class RosterInfoTab(Tab):
|
|||
self.default_help_message = windows.HelpText("Enter commands with “/”. “o”: toggle offline show")
|
||||
self.input = self.default_help_message
|
||||
self.set_color_state(theme.COLOR_TAB_NORMAL)
|
||||
self.key_func['^I'] = self.completion
|
||||
self.key_func['M-i'] = self.completion
|
||||
self.key_func["^J"] = self.on_enter
|
||||
self.key_func["^M"] = self.on_enter
|
||||
self.key_func[' '] = self.on_space
|
||||
self.key_func["/"] = self.on_slash
|
||||
self.key_func["KEY_UP"] = self.move_cursor_up
|
||||
self.key_func["KEY_DOWN"] = self.move_cursor_down
|
||||
self.key_func["o"] = self.toggle_offline_show
|
||||
self.key_func["^F"] = self.start_search
|
||||
self.resize()
|
||||
|
||||
def resize(self):
|
||||
|
@ -644,6 +704,12 @@ class RosterInfoTab(Tab):
|
|||
self.contact_info_win.resize(3, roster_width, self.height-2-3, 0, self.core.stdscr)
|
||||
self.input.resize(1, self.width, self.height-1, 0, self.core.stdscr)
|
||||
|
||||
def completion(self):
|
||||
# Check if we are entering a command (with the '/' key)
|
||||
if isinstance(self.input, windows.CommandInput) and\
|
||||
not self.input.help_message:
|
||||
self.complete_commands(self.input)
|
||||
|
||||
def refresh(self, tabs, informations, roster):
|
||||
if not self.visible:
|
||||
return
|
||||
|
@ -664,22 +730,11 @@ class RosterInfoTab(Tab):
|
|||
self._color_state = color
|
||||
|
||||
def on_input(self, key):
|
||||
key_commands = {
|
||||
"^J": self.on_enter,
|
||||
"^M": self.on_enter,
|
||||
"\n": self.on_enter,
|
||||
' ': self.on_space,
|
||||
"/": self.on_slash,
|
||||
"KEY_UP": self.move_cursor_up,
|
||||
"KEY_DOWN": self.move_cursor_down,
|
||||
"o": self.toggle_offline_show,
|
||||
"^F": self.start_search,
|
||||
}
|
||||
res = self.input.do_command(key)
|
||||
if res:
|
||||
return True
|
||||
if key in key_commands:
|
||||
return key_commands[key]()
|
||||
if key in self.key_func:
|
||||
return self.key_func[key]()
|
||||
|
||||
def toggle_offline_show(self):
|
||||
"""
|
||||
|
@ -793,10 +848,17 @@ class ConversationTab(ChatTab):
|
|||
self.info_win = windows.TextWin()
|
||||
self.tab_win = windows.GlobalInfoBar()
|
||||
self.input = windows.MessageInput()
|
||||
self.commands['unquery'] = (self.command_unquery, _("Usage: /unquery\nUnquery: close the tab"))
|
||||
self.commands['part'] = (self.command_unquery, _("Usage: /part\Part: close the tab"))
|
||||
# keys
|
||||
self.key_func['^I'] = self.completion
|
||||
self.key_func['M-i'] = self.completion
|
||||
# commands
|
||||
self.commands['unquery'] = (self.command_unquery, _("Usage: /unquery\nUnquery: close the tab"), None)
|
||||
self.commands['part'] = (self.command_unquery, _("Usage: /part\Part: close the tab"), None)
|
||||
self.resize()
|
||||
|
||||
def completion(self):
|
||||
self.complete_commands(self.input)
|
||||
|
||||
def command_say(self, line):
|
||||
muc.send_private_message(self.core.xmpp, self.get_name(), line)
|
||||
self.core.add_message_to_text_buffer(self.get_room(), line, None, self.core.own_nick)
|
||||
|
|
|
@ -803,17 +803,20 @@ class Input(Win):
|
|||
self.rewrite_text()
|
||||
return True
|
||||
|
||||
def auto_completion(self, user_list, add_after=True):
|
||||
def auto_completion(self, word_list, add_after):
|
||||
"""
|
||||
Complete the nickname
|
||||
Complete the input, from a list of words
|
||||
if add_after is None, we use the value defined in completion
|
||||
plus a space, after the completion. If it's a string, we use it after the
|
||||
completion (with no additional space)
|
||||
"""
|
||||
if self.pos+self.line_pos != len(self.text): # or len(self.text) == 0
|
||||
return # we don't complete if cursor is not at the end of line
|
||||
completion_type = config.get('completion', 'normal')
|
||||
if completion_type == 'shell' and self.text != '':
|
||||
self.shell_completion(user_list, add_after)
|
||||
self.shell_completion(word_list, add_after)
|
||||
else:
|
||||
self.normal_completion(user_list, add_after)
|
||||
self.normal_completion(word_list, add_after)
|
||||
return True
|
||||
|
||||
def reset_completion(self):
|
||||
|
@ -823,46 +826,48 @@ class Input(Win):
|
|||
self.hit_list = []
|
||||
self.last_completion = None
|
||||
|
||||
def normal_completion(self, user_list, add_after):
|
||||
def normal_completion(self, word_list, after):
|
||||
"""
|
||||
Normal completion
|
||||
"""
|
||||
if add_after and (" " not in self.text.strip() or\
|
||||
self.last_completion and self.text == self.last_completion+config.get('after_completion', ',')+" "):
|
||||
after = config.get('after_completion', ',')+" "
|
||||
#if " " in self.text.strip() and (not self.last_completion or ' ' in self.last_completion):
|
||||
else:
|
||||
after = " " # don't put the "," if it's not the begining of the sentence
|
||||
(y, x) = self._win.getyx()
|
||||
if not self.last_completion:
|
||||
# begin is the begining of the nick we want to complete
|
||||
if self.text.strip() != '':
|
||||
# if self.text.strip() != '' and\
|
||||
# not self.text.endswith(after):
|
||||
if self.text.strip():
|
||||
begin = self.text.split()[-1].lower()
|
||||
else:
|
||||
begin = ''
|
||||
# else:
|
||||
# begin = ''
|
||||
hit_list = [] # list of matching nicks
|
||||
for user in user_list:
|
||||
if user.lower().startswith(begin):
|
||||
hit_list.append(user)
|
||||
for word in word_list:
|
||||
if word.lower().startswith(begin):
|
||||
hit_list.append(word)
|
||||
if len(hit_list) == 0:
|
||||
return
|
||||
self.hit_list = hit_list
|
||||
end = len(begin)
|
||||
else:
|
||||
begin = self.text[-len(after)-len(self.last_completion):-len(after)]
|
||||
if after:
|
||||
begin = self.text[-len(after)-len(self.last_completion):-len(after)]
|
||||
else:
|
||||
begin = self.last_completion
|
||||
self.hit_list.append(self.hit_list.pop(0)) # rotate list
|
||||
end = len(begin) + len(after)
|
||||
self.text = self.text[:-end]
|
||||
if end:
|
||||
self.text = self.text[:-end]
|
||||
nick = self.hit_list[0] # take the first hit
|
||||
self.last_completion = nick
|
||||
self.text += nick +after
|
||||
self.key_end(False)
|
||||
|
||||
def shell_completion(self, user_list, add_after):
|
||||
def shell_completion(self, word_list, after):
|
||||
"""
|
||||
Shell-like completion
|
||||
"""
|
||||
if " " in self.text.strip() or not add_after:
|
||||
if " " in self.text.strip() or add_after is not None:
|
||||
after = " " # don't put the "," if it's not the begining of the sentence
|
||||
else:
|
||||
after = config.get('after_completion', ',')+" "
|
||||
|
@ -872,7 +877,7 @@ class Input(Win):
|
|||
else:
|
||||
begin = ''
|
||||
hit_list = [] # list of matching nicks
|
||||
for user in user_list:
|
||||
for user in word_list:
|
||||
if user.lower().startswith(begin):
|
||||
hit_list.append(user)
|
||||
if len(hit_list) == 0:
|
||||
|
|
Loading…
Reference in a new issue