Start a REPL to evaluate JavaScript code in the extra-module environment. Multi-line statements and readline history are supported. ^C support is sketchy. Exit the REPL with ^D or ".quit".
()
| 151 | |
| 152 | |
| 153 | async def repl(): |
| 154 | """ |
| 155 | Start a REPL to evaluate JavaScript code in the extra-module environment. Multi-line statements and |
| 156 | readline history are supported. ^C support is sketchy. Exit the REPL with ^D or ".quit". |
| 157 | """ |
| 158 | |
| 159 | print('Welcome to PythonMonkey v' + pm.__version__ + '.') |
| 160 | print('Type ".help" for more information.') |
| 161 | readline.parse_and_bind('set editing-mode emacs') |
| 162 | histfile = os.getenv('PMJS_REPL_HISTORY') or os.path.expanduser('~/.pmjs_history') |
| 163 | if (os.path.exists(histfile)): |
| 164 | try: |
| 165 | readline.read_history_file(histfile) |
| 166 | except BaseException: |
| 167 | pass |
| 168 | |
| 169 | got_sigint = 0 |
| 170 | statement = '' |
| 171 | readline_skip_chars = 0 |
| 172 | inner_loop = False |
| 173 | |
| 174 | def save_history(): |
| 175 | nonlocal histfile |
| 176 | readline.write_history_file(histfile) |
| 177 | |
| 178 | import atexit |
| 179 | atexit.register(save_history) |
| 180 | |
| 181 | def quit(): |
| 182 | """ |
| 183 | Quit the REPL. Repl saved by atexit handler. |
| 184 | """ |
| 185 | globalThis.python.exit() # need for python.exit.code in require.py |
| 186 | |
| 187 | def sigint_handler(signum, frame): |
| 188 | """ |
| 189 | Handle ^C by aborting the entry of the current statement and quitting when double-struck. |
| 190 | |
| 191 | Sometimes this happens in the main input() function. When that happens statement is "", because |
| 192 | we have not yet returned from input(). Sometimes it happens in the middle of the inner loop's |
| 193 | input() - in that case, statement is the beginning of a multiline expression. Hitting ^C in the |
| 194 | middle of a multiline express cancels its input, but readline's input() doesn't return, so we |
| 195 | have to print the extra > prompt and fake it by later getting rid of the first readline_skip_chars |
| 196 | characters from the input buffer. |
| 197 | """ |
| 198 | nonlocal got_sigint |
| 199 | nonlocal statement |
| 200 | nonlocal readline_skip_chars |
| 201 | nonlocal inner_loop |
| 202 | |
| 203 | got_sigint = got_sigint + 1 |
| 204 | if (got_sigint > 1): |
| 205 | raise EOFError |
| 206 | |
| 207 | if (not inner_loop): |
| 208 | if (got_sigint == 1 and len(readline.get_line_buffer()) == readline_skip_chars): |
| 209 | # First ^C with nothing in the input buffer |
| 210 | sys.stdout.write("\n(To exit, press Ctrl+C again or Ctrl+D or type .exit)") |