my-yadm/.config/hexchat/addons/pytabcomplete.py

78 lines
2 KiB
Python

from __future__ import print_function
import hexchat
__module_name__ = "PythonTabComplete"
__module_author__ = "TingPing, FichteFoll"
__module_version__ = "0.3"
__module_description__ = "Tab-completes module attributes in Interactive Console"
last_index = None
last_completes = None
last_text = None
last_pos = None
exec_scope = {}
def keypress_cb(word, word_eol, userdata):
global last_index
global last_completes
global last_text
global last_pos
if not word[0] == '65289': # Tab
return
if not hexchat.get_info('channel') == '>>python<<':
return
shift_key_is_down = bool(int(word[1]) & 1) # check if shift modifier is hold
text = hexchat.get_info('inputbox')
pos = hexchat.get_prefs('state_cursor')
if not text:
return
base = text[:pos].split(' ')[-1]
module, _, prefix = base.rpartition('.')
if not module:
# can not dir() the console's interpreter state sadly
return
if last_text != text or last_pos != pos:
# new completion context
try:
exec('import {}'.format(module), exec_scope) # Has to be imported to dir() it
completions = eval('dir({})'.format(module), exec_scope)
except (NameError, SyntaxError, ImportError):
return
completions = [c for c in completions if c.startswith(prefix)]
if not completions:
return
index = 0
else:
# same context, insert next completion
completions = last_completes
direction = 1 if not shift_key_is_down else -1
index = (last_index + direction) % len(completions)
complete_text = completions[index]
new_text = text[:pos - len(prefix)] + complete_text + text[pos:]
new_pos = pos - len(prefix) + len(complete_text)
hexchat.command('settext {}'.format(new_text))
hexchat.command('setcursor {}'.format(new_pos))
last_index = index
last_completes = completions
last_text = new_text
last_pos = new_pos
def unload_cb(userdata):
print(__module_name__, 'version', __module_version__, 'unloaded.')
hexchat.hook_print('Key Press', keypress_cb)
hexchat.hook_unload(unload_cb)
print(__module_name__, 'version', __module_version__, 'loaded.')