Skip to content

Instantly share code, notes, and snippets.

@Carreau
Created March 31, 2022 16:59
Show Gist options
  • Save Carreau/aee8692eefd160d17929703a4c158eaa to your computer and use it in GitHub Desktop.
Save Carreau/aee8692eefd160d17929703a4c158eaa to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "2419149a",
"metadata": {},
"outputs": [],
"source": [
"from IPython.core.completer import IPCompleter, cursor_to_position, position_to_cursor, Completion\n",
"import types\n",
"import parso\n",
"\n",
"\n",
"# try to avoid recursive patching if rerun.\n",
"if getattr(IPCompleter,'_patched', False) == False:\n",
" original_method = IPCompleter._completions \n",
" IPCompleter._patched = True\n",
"\n",
"\n",
"def my_completer(self, full_text: str, offset: int, *, _timeout):\n",
" \n",
" # there is either bytes, coordinate in test, and/or rows/columns either 0 or 1 index, \n",
" # the hard part is converting between those.\n",
" \n",
" # here i'm using parso to find \"if\" we are in a string\n",
" # and find the beginning of the string, you don't have to do do that. \n",
" pos = position_to_cursor(full_text, offset)\n",
" pos_parso = pos[0]+1, pos[1]\n",
" tree = parso.parse(full_text)\n",
" t = tree.get_leaf_for_position(pos_parso)\n",
" from there import syslogprint\n",
" syslogprint(t, t.type)\n",
" if t.type == 'string': # might not be 'string' is the string quotes is not closed, may be 'name'.\n",
" start_pos = t.start_pos[0]-1, t.start_pos[1]\n",
" start_index = cursor_to_position(full_text, *start_pos)+1 \n",
" stop_index = offset\n",
" interesting_text=full_text[start_index:stop_index]\n",
" if interesting_text.startswith('test'):\n",
" # do you best logic here.\n",
" for item in ['testaa','test_bb','test-cc', 'test*dd', 'test:ee', '¯\\_(ツ)_/¯ == 🤷']:\n",
" yield Completion(\n",
" start_index, # the start of what it will replace,\n",
" stop_index, # the end of what it will repalce/\n",
" item, # by what it will be replaced.\n",
" # this shoudl make the completer show \"signature\" next to the completion\n",
" # if you use \"function\" \n",
" # in the terminal at least, I don't think it's supported in JupyterLab\n",
" type='function', \n",
" _origin='jedi', \n",
" signature='(some metainfo)')\n",
" # let's keep original results, again you don't have to.\n",
" yield from original_method(self, full_text, offset, _timeout=_timeout)\n",
" \n",
"\n",
"# this should be sufficient in a startup file or configuration file, if it's done _before_ IPython start \n",
"IPCompleter._completions = my_completer\n",
" \n",
"# this in a live IPython. \n",
"# be careful with re-running or you may end up with recursiosn errors.\n",
"ip = get_ipython()\n",
"ip.Completer._completions = types.MethodType(my_completer, ip.Completer)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "0d60ef88",
"metadata": {},
"outputs": [],
"source": [
"for i in ['this', 'is', 'test:' ]:\n",
" pass\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0b25124d",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment