Alguma maneira de o shell do emacs passar o TAB para um comando readline sendo executado dentro dele?

8

Por exemplo. quando você executa coisas legais como Perl ou Ruby REPLs, você tem a conclusão de código / comando exposta via GNU Readline. O que eu quero fazer é definir alguma variável elisp / env ao entrar / sair desse programa para indicar que eu quero shell-modepassar a tecla TAB para esses programas.

Note que C-q TABtambém não funciona, então acho que o Readline também o está ignorando porque TERM=dumb, mas configurando-o como por exemplo. O vt100 também não funciona, por isso pode até estar olhando EMACS=t.

Mark Aufflick
fonte
3
Comint não funciona assim. Aguarda o envio de uma linha RETe recebe a saída até reconhecer um prompt. A conclusão deve, portanto, ser resolvida de lado.
Wasamasa
Dê uma olhada no ESS ou no modo grama para ver como a conclusão é tratada diretamente no elisp no lado do Emacs, em vez de depender da linha de leitura.
Tyler
Isso também seria útil para o modo Prolog, onde pressionar Tab deve solicitar ao intérprete que gere a próxima solução.
Wvxvw
@ Tyler, é onde o conhecimento existe em outro lugar (por exemplo, em um intérprete em execução). Acho que eu poderia fazer algum tipo de procuração readline que poderia ter conclusão delegada a ele de lisp - parece ser um monte de trabalho :)
Mark Aufflick
O @MarkAufflick ESS faz algo assim, eu acho, com a maioria das conclusões fornecidas via elisp, mas alguns casos / situações especiais foram passados ​​para o processo R. Os casos especiais podem resultar em conclusões dolorosamente lentas.
Tyler

Respostas:

2

M-x shelltrabalha linha por vez. Ele passa uma linha de entrada para o processo de shell externo quando você pressiona a Rettecla.

M-x termpassa cada pressionamento de tecla para o processo externo do shell, com as exceções de C-ce eu acho Esc. Quando você pressiona Tab, será visto e interpretado pelo processo de shell externo.

user20119
fonte
2

Como @ user20119 apontou, M-x termpode ser uma boa opção: ele também suporta a mudança dinâmica para o "modo de linha", que é um pouco semelhante ao que você obtém M-x shell.

M-x eshell também tenta fornecer uma mistura dos dois comportamentos.

Também vou apontar que C-q TABnão funcionou porque tudo o que faz é inserir um caractere TAB no buffer (em vez de enviar um TAB para o subprocesso). Além disso, apenas enviar um caractere TAB para o processo subjacente não seria suficiente, porque o texto na linha atual ainda não foi enviado ao processo, portanto, você pode precisar de algo como:

(defun my-comint-tab ()
  (interactive)
  (let* ((proc (get-buffer-process (current-buffer)))
         (str (buffer-substring (process-mark proc) (point))))
    (process-send-string proc (concat str "\t"))))

e, de fato, você provavelmente também precisará convencer M-x shella usar uma configuração diferente para $TERM.

Stefan
fonte