Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add group UI wrapper #8

Merged
merged 6 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions libs/ide_services/__init__.py
Original file line number Diff line number Diff line change
@@ -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"]
15 changes: 15 additions & 0 deletions libs/ide_services/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
11 changes: 8 additions & 3 deletions libs/ui_utils/__init__.py
Original file line number Diff line number Diff line change
@@ -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__ = [
Expand All @@ -13,4 +14,8 @@
"ui_text_edit",
"CheckboxOption",
"RadioOption",
"make_checkbox_control",
"make_radio_control",
"make_editor_control",
"ui_group",
Comment on lines +17 to +20
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

新增暴露make_*_control系列接口 跟前面的 ui_*的区别是什么?像commit.py里仍用的ui_*系列,新暴露的函数并没有在外使用,那么他们应该什么时候被用到?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

大概是这样使用:
(check_result, edit_result) = ui_group(
make_check_control(...),
make_editor_control(...)
)
make_checkbox_control用于生成复合UI规范的描述字符串。

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

把使用示例和效果截图补充到PR description里吧

]
36 changes: 36 additions & 0 deletions libs/ui_utils/group.py
Original file line number Diff line number Diff line change
@@ -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)
41 changes: 22 additions & 19 deletions libs/ui_utils/multi_selections.py
Original file line number Diff line number Diff line change
Expand Up @@ -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())

Expand All @@ -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)
39 changes: 20 additions & 19 deletions libs/ui_utils/single_select.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
44 changes: 26 additions & 18 deletions libs/ui_utils/text_edit.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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)