How can I add my own autocompletion words?
itsToggle opened this issue · 14 comments
Hey, thanks so much for this project, its been a wonderful addition to my projects :)
I noticed that the section on autocompletion/snippets is not finished in the docs, could you give any hints as to how I could implement basic autocompletion for a list of words?
Thanks!
The feature to add/remove autocompletion tokens is not finished. You can only turn it on off.
However, there is a way to add/remove snippets.
response = code_editor(code_text, snippets=["",""])
The above example shows the default value for the snippets
argument of code_editor
. I show this to you to explain that the first element of the array is where you will place the snippets you want to add and the second element is where you want to place the array of snippets you want to remove.
Example: Add markdown snippets while removing none of the pre-existing snippets.
reveal_snippets = [[{
"name": '--',
"code": '\n---\n## New Horizontal Slide\n'
},
{
"name": 'new slide (horizontal)',
"code": '\n---\n## New Horizontal Slide\n'
},
{
"name": '-',
"code": '\n--\n## New Vertical Slide\n'
},
{
"name": 'new slide (vertical)',
"code": '--\n## New Vertical Slide\n'
},
{
"name": '<!-- .s',
"code": '<!-- .slide: -->'
},
{
"name": '<!-- .e',
"code": '<!-- .element: class="fragment" class="fragment" -->'
},
{
"name": 'slide attributes',
"code": '<!-- .slide: -->'
},
{
"name": 'element attributes',
"code": '<!-- .element: class="fragment" class="fragment" -->'
}
],""] # <-- notice the empty string. This tells code editor to not remove any snippets. This is also necessary to ensure the expected format
response = code_editor(code_text, lang="markdown", snippets=reveal_snippets)
Hopefully the example is helpful.
I will try to work on adding a new argument that allows you to add/remove autocomplete tokens/words
I forgot to mention. I think you can provide the snippets you want to add or remove in either an array like in the example above or as a string.
As an example, I will list the default snippets for python (commented out):
#snippet #!
# #!/usr/bin/env python
#snippet imp
# import ${1:module}
#snippet from
# from ${1:package} import ${2:module}
#snippet docs
# '''
# File: ${1:FILENAME:file_name}
# Author: ${2:author}
# Description: ${3}
# '''
#snippet wh
# while ${1:condition}:
# ${2:# TODO: write code...}
#snippet dowh
# while True:
# ${1:# TODO: write code...}
# if ${2:condition}:
# break
#snippet with
# with ${1:expr} as ${2:var}:
# ${3:# TODO: write code...}
#snippet cl
# class ${1:ClassName}(${2:object}):
# """${3:docstring for $1}"""
# def __init__(self, ${4:arg}):
# ${5:super($1, self).__init__()}
# self.$4 = $4
# ${6}
#snippet def
# def ${1:fname}(${2:`indent('.') ? 'self' : ''`}):
# """${3:docstring for $1}"""
# ${4:# TODO: write code...}
#snippet deff
# def ${1:fname}(${2:`indent('.') ? 'self' : ''`}):
# ${3:# TODO: write code...}
#snippet defs
# def ${1:mname}(self, ${2:arg}):
# ${3:# TODO: write code...}
#snippet property
# def ${1:foo}():
# doc = "${2:The $1 property.}"
# def fget(self):
# ${3:return self._$1}
# def fset(self, value):
# ${4:self._$1 = value}
#snippet if
# if ${1:condition}:
# ${2:# TODO: write code...}
#snippet el
# else:
# ${1:# TODO: write code...}
#snippet ei
# elif ${1:condition}:
# ${2:# TODO: write code...}
#snippet for
# for ${1:item} in ${2:items}:
# ${3:# TODO: write code...}
#snippet cutf8
# # -*- coding: utf-8 -*-
#snippet clatin1
# # -*- coding: latin-1 -*-
#snippet cascii
# # -*- coding: ascii -*-
#snippet ld
# ${1:var} = lambda ${2:vars} : ${3:action}
#snippet .
# self.
#snippet try Try/Except
# try:
# ${1:# TODO: write code...}
# except ${2:Exception}, ${3:e}:
# ${4:raise $3}
#snippet try Try/Except/Else
# try:
# ${1:# TODO: write code...}
# except ${2:Exception}, ${3:e}:
# ${4:raise $3}
# else:
# ${5:# TODO: write code...}
#snippet try Try/Except/Finally
# try:
# ${1:# TODO: write code...}
# except ${2:Exception}, ${3:e}:
# ${4:raise $3}
# finally:
# ${5:# TODO: write code...}
#snippet try Try/Except/Else/Finally
# try:
# ${1:# TODO: write code...}
# except ${2:Exception}, ${3:e}:
# ${4:raise $3}
# else:
# ${5:# TODO: write code...}
# finally:
# ${6:# TODO: write code...}
#snippet ifmain
# if __name__ == '__main__':
# ${1:main()}
#snippet _
# __${1:init}__${2}
#snippet pdb
# import pdb; pdb.set_trace()
#snippet ipdb
# import ipdb; ipdb.set_trace()
#snippet pdbbb
# import pdbpp; pdbpp.set_trace()
#snippet pprint
# import pprint; pprint.pprint(${1})${2}
#snippet "
# """
# ${1:doc}
# """
#snippet test
# def test_${1:description}(${2:self}):
# ${3:# TODO: write code...}
#snippet testcase
# class ${1:ExampleCase}(unittest.TestCase):
#
# def test_${2:description}(self):
# ${3:# TODO: write code...}
#snippet fut
# from __future__ import ${1}
#snippet getopt
# try:
# # Short option syntax: "hv:"
# # Long option syntax: "help" or "verbose="
# opts, args = getopt.getopt(sys.argv[1:], "${1:short_options}", [${2:long_options}])
#
# except getopt.GetoptError, err:
# # Print debug info
# print str(err)
# ${3:error_action}
#
# for option, argument in opts:
# if option in ("-h", "--help"):
# ${4}
# elif option in ("-v", "--verbose"):
# verbose = argument
For a guide to writing snippets see here
Awesome! Thanks 👍
For my purposes this would close the issue.
Hey @bouzidanas - Thanks for this wonderful component. I've been trying to figure out how to use the new completions
and replace_completer
params, but can't seem to get it working. Are you still planning to update the docs to address those latest changes? Thanks!
Hi @ewoo17 ,
I got pulled away from that to fix some issues in another package. I will add some info that should help soon.
Hi again @ewoo17
New section in the docs covering completions:
https://code-editor-documentation.streamlit.app/Advanced_customization#custom-completions
@bouzidanas I've copied your example in the docs into a very basic streamlit app, however I don't see the completion. Any ideas?
version:
% pip show streamlit_code_editor
Name: streamlit-code-editor
Version: 0.1.20
Summary: React-ace editor customized for Streamlit
Home-page: https://github.com/bouzidanas/streamlit-code-editor
Author: Anas Bouzid
Author-email: anasbouzid@gmail.com
License:
Location: <path_to_working_dir>/venv/lib/python3.12/site-packages
Requires: streamlit
Required-by:
app.py
, running streamlit run app.py
:
import streamlit as st
from code_editor import code_editor
response_dict = code_editor(
"a bunch of random stuff",
lang="python",
completions=[{"caption": "AAA", "value": "BBB", "meta": "CCC", "name": "DDD", "score": 400}],
height=[25, 25],
)
Found out what the issue was. The latest package version number was incorrect. The 2
in 0.1.20
was for some reason changed to a 1
.
That is now corrected and a new version of the package was uploaded. Please update the package by running
pip install -U streamlit-code-editor
Awesome, that worked. Thanks for the quick help!
Thank you for making me aware of the issue!
So looks like with replace_completer=True
you pop()
the keyWordCompleter
of the specific language mode off, however, the textCompleter
(local words/variables) remains - wondering if that's by intention or what your thoughts were when planning it out?
fyi: For my use case/language, I'd rather not see those suggestions for every word that ends up being typed in the editor, as they end up not being useful/anything the user would want to potentially type.
perhaps instead of replace_completer: bool
, it could instead be remove_completers: str | list[str]
of which completers to remove (text/word/local/variable
, keyword
, or snippet
) - or other way around as include_completers
?
see:
completers
list order: https://github.com/bouzidanas/streamlit-code-editor/blob/master/code_editor/frontend/node_modules/ace-builds/src/ext-language_tools.js#L2435C37-L2435C68textCompleter
: https://github.com/bouzidanas/streamlit-code-editor/blob/master/code_editor/frontend/node_modules/ace-builds/src/ext-language_tools.js#L2353- securingsincity/react-ace#532 (comment)
Very very good catch @ewoo17 !!
That is not intentional!
I like your proposition of remove_completers
. I will try to get to it soon or alternatively you can make the changes, test them, then submit a pull request.
The relevant bit of code is:
if(replaceCompleter) {
editorRef.current.editor.completers.pop();
}
in https://github.com/bouzidanas/streamlit-code-editor/blob/master/code_editor/frontend/src/editor.tsx
I probably won't have the time at the moment to address this testing-wise although I could def submit a change for you to test if you'd like lol (would be my first time building the component locally too) but maybe for future issues! Not the most pressed with this issue as my completions would load above the local
suggestions
No worries. I will probably get this done late Friday. Thanks for looking into it and finding the source of the issue! Im solo developing this and many other projects in my free time so fixes can be a little slow at times.