| 874 | } |
| 875 | |
| 876 | void start_embedded_repl(int read_fd, int write_fd) { |
| 877 | stop_embedded_repl(); |
| 878 | ensure_initialized(); |
| 879 | |
| 880 | auto& pm = PackageManager::instance(); |
| 881 | if (!pm.is_installed("ptpython")) { |
| 882 | LOG_INFO("Installing ptpython..."); |
| 883 | const auto result = pm.install("ptpython"); |
| 884 | if (!result.success) { |
| 885 | LOG_WARN("Failed to install ptpython: {} (falling back to code.interact)", result.error); |
| 886 | } else { |
| 887 | update_python_path(); |
| 888 | } |
| 889 | } |
| 890 | |
| 891 | g_repl_read_fd = read_fd; |
| 892 | g_repl_write_fd = write_fd; |
| 893 | g_repl_running = true; |
| 894 | |
| 895 | g_repl_thread = std::thread([read_fd, write_fd]() { |
| 896 | { |
| 897 | const GilAcquire gil; |
| 898 | install_output_redirect(); |
| 899 | |
| 900 | SceneContextGuard ctx(get_application_scene()); |
| 901 | |
| 902 | const std::string setup = std::format(R"( |
| 903 | import sys, os, atexit |
| 904 | |
| 905 | _repl_read_fd = {} |
| 906 | _repl_write_fd = {} |
| 907 | _repl_in = os.fdopen(os.dup(_repl_read_fd), 'r', buffering=1) |
| 908 | _repl_out = os.fdopen(os.dup(_repl_write_fd), 'w', buffering=1) |
| 909 | |
| 910 | _saved_stdin = sys.stdin |
| 911 | _saved_stdout = sys.stdout |
| 912 | _saved_stderr = sys.stderr |
| 913 | sys.stdin = _repl_in |
| 914 | sys.stdout = _repl_out |
| 915 | sys.stderr = _repl_out |
| 916 | |
| 917 | import lichtfeld as lf |
| 918 | _repl_locals = {{"lf": lf, "__name__": "__console__", "__doc__": None}} |
| 919 | |
| 920 | _histfile = os.path.join(os.path.expanduser("~"), ".lichtfeld", "repl_history") |
| 921 | os.makedirs(os.path.dirname(_histfile), exist_ok=True) |
| 922 | |
| 923 | _used_ptpython = False |
| 924 | try: |
| 925 | from ptpython.repl import embed as _pt_embed |
| 926 | from prompt_toolkit.output.vt100 import Vt100_Output |
| 927 | from prompt_toolkit.data_structures import Size |
| 928 | from prompt_toolkit.application import create_app_session |
| 929 | |
| 930 | _pt_output = Vt100_Output(_repl_out, get_size=lambda: Size(rows=24, columns=80), enable_cpr=False) |
| 931 | _pt_input = None |
| 932 | if not _repl_in.isatty(): |
| 933 | from prompt_toolkit.input.vt100 import Vt100Input |
no test coverage detected