Trabajando con curses en IPython. ¿Cómo puedo mejorar esto?
He encontrado una forma de trabajar de forma interactiva con cursas mientras disfruto de la mayoría de los beneficios de IPython. Funciona, con algunas limitaciones, pero no tan bien como me gustaría.
El problema original, por supuesto, es que me gustaría poder trabajar con mi sesión interactiva de Python mientras tengo que controlar una pantalla de terminal, usando el módulo de curses (ncurses) (oUrwid, por ejemplo). Una solución es escribir un servidor TCP simple con un bucle de eventos simple que evalúe cada cadena que lee desde el socket y enviar cadenas serializadas que representen y devuelvan resultados. Como se describe aquí:SO: ¿Hay una manera de programar interactivamente una aplicación de curses Python?).
Aquí hay un truco un tanto más simple (asumiendo que tiene instalado IPython).
#!/usr/bin/python
#!/usr/bin/env python
from IPython import embed_kernel
import curses
def interact_with_curses(screen):
'''set global stdscr variable and run embedded IPython kernel
suitable to be called by curses.wrapper()
'''
global stdscr
stdscr = screen
embed_kernel()
if __name__ == '__main__':
curses.wrapper(interact_with_curses)
(un poco munged para que la sintaxis de SO resulte feliz).
Ejecutar esto dará como resultado una salida más o menos como:
[IPKernelApp] To connect another client to this kernel, use:
[IPKernelApp] --existing kernel-2869.json
Y cambiando a otra ventana o sesión de pantalla puedes ejecutar:
ipython console --existing kernel-2869.json
Para conectarse a ese proceso y trabajar con él.
Esto es lo suficientemente bueno. A continuación, puede llamar a cosas comostdscr.refresh()
. Trabaja con tus objetos de curses / ventana y pad, llamadir()
en ellos para explorar su funcionalidad y, por lo general, trabajar con el código como si estuviera en una sesión normal de IPython, que simplemente está actualizando la pantalla de un terminal diferente y leyendo también (a través de las funciones de entrada de curses).
Problemas con este enfoque, y preguntas:
Para salir, parece que tengo que ejecutar quit () desde la consola IPython, y esto no sale del intérprete en los medios normales. No parece permitircurses.wrapper()
para restablecer el terminal y varios intentos de llamada.endwin()
, .resetty()
(después de haber realizado una.savetty()
por supuesto),.reset_shell_mode()
(y.reset_prog_mode()
) y así sucesivamente todos han fallado. He intentado llamarlos en main después de la llamada acurses.wrapper()
y he intentado registrarlos conatexit
¿Cómo salgo limpiamente de tal sesión?[Tab] la finalización no funciona¿Cómo consigo que la [Pestaña] de IPython funcione completamente a través de una sesión de consola de IPython en uno de estos núcleos incrustados?Llamando al IPythonembed_kernel()
La función imprime la información del socket en la pantalla de curses, que ya está inicializada porcurses.wrapper()
en ese momento Esto es feo También si quieres hacer un trabajo más interesante, en curses y antes de llamar alembed_kernel()
luego no puedo ver el texto que se imprimió en stdout o stderr por esa función.Como hagoembed_kernel()
¿Silencio y obligarlo a registrar los detalles de conexión a través de algún otro mecanismo? ¿Puedo darle mi propio nombre / ruta de socket para usar?Estoy seguro de que pensaré en otras preguntas, pero espero que otros encuentren útil este truco y descubran algunos otros trucos que puedo usar cuando quiera meterme con la codificación de curses de Python.