Trabalhando com curses no IPython. Como posso melhorar isso?
Eu encontrei uma maneira de trabalhar interativamente com maldições enquanto ainda aproveito a maioria dos benefícios do IPython. Funciona, com algumas limitações, mas não tão bem quanto gostaria.
O problema original, é claro, é que eu gostaria de poder trabalhar com a minha sessão interativa do Python enquanto ela controla uma tela de terminal, usando o módulo curses (ncurses) (ouurwid, por exemplo). Uma solução é escrever um servidor TCP simples com um loop de eventos simples que avalie cada string que lê no soquete e envie de volta seqüências serializadas representando e retornando resultados. Como descrito aqui:SO: Existe uma maneira de programar interativamente um aplicativo Python curses).
Aqui está um truque um pouco mais simples (supondo que você tenha o IPython instalado).
#!/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)
(ligeiramente munged para obter a sintaxe do SO destacando feliz).
Rodar isto resultará em uma saída mais ou menos como:
[IPKernelApp] To connect another client to this kernel, use:
[IPKernelApp] --existing kernel-2869.json
E mudar para outra janela ou sessão de tela você pode executar:
ipython console --existing kernel-2869.json
Para se conectar a esse processo e trabalhar com ele.
Isso é bom o suficiente. Você pode então chamar coisas comostdscr.refresh()
. Trabalhe com seus curses / window e pad objects, calldir()
sobre eles para explorar sua funcionalidade e geralmente trabalhar com o código como se você estivesse em uma sessão normal do IPython que por acaso esteja atualizando a tela de um terminal diferente e lendo também (através das funções de entrada curses).
Problemas com esta abordagem e questões:
Para sair, parece que tenho que executar o quit () no console do IPython, e isso não sai do interpretador nos meios normais. Não parece permitircurses.wrapper()
para redefinir o terminal e várias tentativas de chamada.endwin()
, .resetty()
(depois de ter realizado um.savetty()
claro),.reset_shell_mode()
(e.reset_prog_mode()
) e assim por diante todos falharam. Eu tentei chamá-los no principal após a chamada paracurses.wrapper()
e eu tentei registrá-los comatexit
Como posso sair de uma sessão assim?A conclusão [Tab] não funcionaComo faço para que o [Tab] do IPython trabalhe completamente através de uma sessão de console do IPython em um desses kernels embeded?Chamando o IPythonembed_kernel()
função imprime as informações do soquete para a tela curses, que já é inicializada pelocurses.wrapper()
por esse tempo. Isso é feio; também se quiser fazer um trabalho mais interessante, em maldições e antes de chamar oembed_kernel()
função, então não consigo ver o texto que foi impresso para stdout ou stderr por essa função.Como eu façoembed_kernel()
silencioso e forçá-lo a registrar os detalhes da conexão através de algum outro mecanismo? Posso dar o meu próprio nome de socket / caminho para usar?Tenho certeza de que vou pensar em outras questões, mas espero que os outros achem esse truque útil e descubram alguns outros truques que eu possa usar quando quero me envolver com o código Python.