diff --git a/libs/ide_services/__init__.py b/libs/ide_services/__init__.py index 73ddb1b..d1bbe1f 100644 --- a/libs/ide_services/__init__.py +++ b/libs/ide_services/__init__.py @@ -1,3 +1,3 @@ -from .services import get_lsp_brige_port +from .services import get_lsp_brige_port, install_python_env, update_slash_commands, open_folder -__all__ = ["get_lsp_brige_port"] +__all__ = ["get_lsp_brige_port", "install_python_env", "update_slash_commands", "open_folder"] diff --git a/libs/ide_services/services.py b/libs/ide_services/services.py index d836fd7..c6a029a 100644 --- a/libs/ide_services/services.py +++ b/libs/ide_services/services.py @@ -31,3 +31,18 @@ def wrapper(*args, **kwargs): @rpc_call def get_lsp_brige_port(): pass + + +@rpc_call +def install_python_env(command_name: str, requirements_file: str) -> str: + pass + + +@rpc_call +def update_slash_commands(): + pass + + +@rpc_call +def open_folder(folder: str): + pass diff --git a/libs/ui_utils/__init__.py b/libs/ui_utils/__init__.py index f32af2c..d5a27b3 100644 --- a/libs/ui_utils/__init__.py +++ b/libs/ui_utils/__init__.py @@ -1,7 +1,8 @@ from .iobase import parse_response_from_ui, pipe_interaction, pipe_interaction_mock -from .multi_selections import ui_checkbox_select, CheckboxOption -from .single_select import ui_radio_select, RadioOption -from .text_edit import ui_text_edit +from .multi_selections import ui_checkbox_select, CheckboxOption, make_checkbox_control +from .single_select import ui_radio_select, RadioOption, make_radio_control +from .text_edit import ui_text_edit, make_editor_control +from .group import ui_group __all__ = [ @@ -13,4 +14,8 @@ "ui_text_edit", "CheckboxOption", "RadioOption", + "make_checkbox_control", + "make_radio_control", + "make_editor_control", + "ui_group", ] diff --git a/libs/ui_utils/group.py b/libs/ui_utils/group.py new file mode 100644 index 0000000..6183fb8 --- /dev/null +++ b/libs/ui_utils/group.py @@ -0,0 +1,36 @@ +from typing import List, Tuple + +from .iobase import pipe_interaction +from .multi_selections import checkbox_answer +from .single_select import radio_answer +from .text_edit import editor_answer + + +def ui_group(ui_message: List[Tuple]) -> Tuple: + """ + ui_message: List[Tuple] + [ + ("editor", "editor ui message", "editor_id"), + ("checkbox", "checkbox ui message", ["id1", "id2"]), + ("radio", "radio ui message", ["id1", "id2"]), + ] + + items in ui_message are created by functions like:make_checkbox_control + """ + ui_message_str = "\n".join([m[1] for m in ui_message]) + + ui_message_str = f"""```chatmark type=form\n{ui_message_str}\n```\n""" + response = pipe_interaction(ui_message_str) + + results = [] + for m in ui_message: + if m[0] == "editor": + result = editor_answer(response, m[2]) + elif m[0] == "checkbox": + result = checkbox_answer(response, m[2]) + elif m[0] == "radio": + result = radio_answer(response, m[2]) + else: + result = None + results.append(result) + return tuple(results) diff --git a/libs/ui_utils/multi_selections.py b/libs/ui_utils/multi_selections.py index 0015b75..f406279 100644 --- a/libs/ui_utils/multi_selections.py +++ b/libs/ui_utils/multi_selections.py @@ -12,16 +12,7 @@ def __init__(self, id, text, group: str = None, checked: bool = False): self._checked = checked -def ui_checkbox_select(title: str, options: List[CheckboxOption]) -> List[str]: - """ - send text to UI as: - ```chatmark - Which files would you like to commit? I've suggested a few. - > [x](file1) devchat/engine/prompter.py - > [x](file2) devchat/prompt.py - > [](file3) tests/test_cli_prompt.py - ``` - """ +def make_checkbox_control(title: str, options: List[CheckboxOption]) -> (str, str, List[str]): _NT = "\n" groups = list({option._group: 1 for option in options if option._group}.keys()) @@ -35,18 +26,30 @@ def _check_option_group_message(group): return f"{group}:{_NT}{s}" ui_message = f""" -```chatmark type=form {title} {_NT.join([_check_option_group_message(group) for group in groups])} -``` """ + return ("checkbox", ui_message, [option._id for option in options]) + + +def checkbox_answer(response: dict, ids: List[str]) -> List[str]: + return [key for key, value in response.items() if value == "checked" and key in ids] + + +def ui_checkbox_select(title: str, options: List[CheckboxOption]) -> List[str]: + """ + send text to UI as: + ```chatmark + Which files would you like to commit? I've suggested a few. + > [x](file1) devchat/engine/prompter.py + > [x](file2) devchat/prompt.py + > [](file3) tests/test_cli_prompt.py + ``` + """ + _1, ui_message, ids = make_checkbox_control(title, options) + ui_message = f"""```chatmark type=form\n{ui_message}\n```\n""" + # print(ui_message) # return [option._id for option in options] response = pipe_interaction(ui_message) - - selected_options = [ - key - for key, value in response.items() - if value == "checked" and key in [option._id for option in options] - ] - return selected_options + return checkbox_answer(response, ids) diff --git a/libs/ui_utils/single_select.py b/libs/ui_utils/single_select.py index b27c91f..5dd4bc5 100644 --- a/libs/ui_utils/single_select.py +++ b/libs/ui_utils/single_select.py @@ -10,32 +10,33 @@ def __init__(self, id, text): self._text = text -def ui_radio_select(title: str, options: List[RadioOption]) -> str | None: - """ - ```chatmark type=form - How would you like to make the change? - > - (insert) Insert the new code. - > - (new) Put the code in a new file. - > - (replace) Replace the current code. - ``` - """ - +def make_radio_control(title: str, options: List[RadioOption]) -> (str, str, List[str]): def _option_line(option): return f"> - ({option._id}) {option._text}" options_lines = "\n".join([_option_line(option) for option in options]) ui_message = f""" -```chatmark type=form {title} {options_lines} -``` """ + return ("radio", ui_message, [option._id for option in options]) - response = pipe_interaction(ui_message) - selected_options = [ - key - for key, value in response.items() - if value == "checked" and key in [option._id for option in options] - ] - return selected_options[0] if len(selected_options) > 0 else None +def radio_answer(response: dict, ids: List[str]) -> str | None: + selected_options = [key for key, value in response.items() if value == "checked" and key in ids] + return selected_options[0] if selected_options else None + + +def ui_radio_select(title: str, options: List[RadioOption]) -> str | None: + """ + ```chatmark type=form + How would you like to make the change? + > - (insert) Insert the new code. + > - (new) Put the code in a new file. + > - (replace) Replace the current code. + ``` + """ + _1, ui_message, ids = make_radio_control(title, options) + ui_message = f"""```chatmark type=form\n{ui_message}\n```\n""" + response = pipe_interaction(ui_message) + return radio_answer(response, ids) diff --git a/libs/ui_utils/text_edit.py b/libs/ui_utils/text_edit.py index 491fe24..a93b2b1 100644 --- a/libs/ui_utils/text_edit.py +++ b/libs/ui_utils/text_edit.py @@ -1,6 +1,29 @@ from .iobase import pipe_interaction +def make_editor_control(editor_id: str, title: str, text: str) -> (str, str, str): + text_lines = text.strip().split("\n") + if len(text_lines) > 0 and text_lines[0].strip().startswith("```"): + text_lines = text_lines[1:] + if len(text_lines) > 0 and text_lines[-1].strip() == "```": + text_lines = text_lines[:-1] + text = "\n".join(text_lines) + text = text.replace("\n", "\n> ") + ui_message = f""" +{title} + +> | ({editor_id}) +> {text} +""" + return ("editor", ui_message, editor_id) + + +def editor_answer(response: dict, editor_id: str) -> str | None: + if editor_id in response: + return response[editor_id] + return None + + def ui_text_edit(title: str, text: str) -> str | None: """ ```chatmark type=form @@ -16,22 +39,7 @@ def ui_text_edit(title: str, text: str) -> str | None: > Refs: #123 ``` """ - text_lines = text.strip().split("\n") - if len(text_lines) > 0 and text_lines[0].strip().startswith("```"): - text_lines = text_lines[1:] - if len(text_lines) > 0 and text_lines[-1].strip() == "```": - text_lines = text_lines[:-1] - text = "\n".join(text_lines) - text = text.replace("\n", "\n> ") - ui_message = f""" -```chatmark type=form -{title} - -> | (editor0) -> {text} -``` -""" + _1, ui_message, editor_id = make_editor_control("editor0", title, text) + ui_message = f"""```chatmark type=form\n{ui_message}\n```\n""" response = pipe_interaction(ui_message) - if "editor0" in response: - return response["editor0"] - return None + return editor_answer(response, editor_id)