Mesclar histórico de vários eshells


9

Antes de mudar para o eshell, eu tinha a configuração do zsh para que:

  • Grave no arquivo de histórico após cada comando
  • Acrescente ao invés de sobrescrever o arquivo de histórico, portanto, ao executar vários shells, todos eles serão mesclados em um grande histórico

As duas opções do zsh estão documentadas aqui (consulte APPEND_HISTORY e INC_APPEND_HISTORY).

Isso é super útil quando combinado com um grande tamanho de histórico, porque você pode abrir um novo shell semanas após emitir um comando e encontrá-lo em seu histórico (sem essas opções, um histórico grande é inútil, pois conterá apenas o histórico dos mais recentes Concha). Isso também significa que você pode abrir novos shells e fazer com que eles conheçam imediatamente seus comandos mais recentes em outros shells. Existe alguma maneira de configurar eshell com esse comportamento? A primeira bala parece fácil o suficiente, mas anexar parece mais difícil ...

Respostas:


3

Disclaimer: Eu não uso eshell, então leve isso com um grão de sal.

eshellparece chamar eshell-write-historypara escrever o histórico, que usa um argumento opcional appendque é o padrão nil. Esse argumento parece não ser usado no eshellmomento, mas parece funcionar (ele passa o argumento para write-region, que é anexado corretamente).

Existem algumas opções aqui.

  1. (setq eshell-save-history-on-exit nil)e chame a eshell-write-historysi mesmo
  2. Redefina eshell-write-historypara satisfazer sua exigência.

Pessoalmente, eu iria com 1.

Como um exemplo:

(setq eshell-save-history-on-exit nil)
(defun eshell-append-history ()
  "Call `eshell-write-history' with the `append' parameter set to `t'."
  (when eshell-history-ring
    (let ((newest-cmd-ring (make-ring 1)))
      (ring-insert newest-cmd-ring (car (ring-elements eshell-history-ring)))
      (let ((eshell-history-ring newest-cmd-ring))
        (eshell-write-history eshell-history-file-name t)))))
(add-hook eshell-pre-command-hook #'eshell-append-history)

Graças a @ joseph-garvin pela eshell-append-historyfunção de trabalho corrigida

Isso não lida com o carregamento dinâmico do novo conteúdo do histórico em um shell (por exemplo, execute o comando Xno shell A e faça com que apareça no histórico no shell B sem recarregar; como o SHARE_HISTORY do zsh). Eu não sei o quão eficiente eshell-read-historyé, então eu hesitaria em executá-lo em um gancho.

Também é possível que você acabe com entradas duplicadas com esta eshell-append-historyfunção. Pode ser necessário fazer algumas travessuras para limpar todas as entradas eshell-history-ring, exceto a mais recente , e depois redefini-la para o valor antigo após escrever o histórico.

Por exemplo

(let ((old-ring (copy-list eshell-history-ring)))
  (setq eshell-history-ring (list (car eshell-history-ring)))
  ; write
  (setq eshell-history-ring old-ring))

Obrigado, isso parece ótimo. No entanto, seu primeiro snippet está faltando uma citação no final da sequência de caracteres.
— Joseph Garvin

Eu tive que editar alguns, acontece que os anéis precisam ser modificados pelas funções ring- * ou você pode encontrar erros. Também uso a ligação dinâmica para substituir temporariamente a definição de eshell-history-ring em vez de fazer uma cópia. Se você colocar o código aqui em sua resposta que eu vou marcar como aceite desde que você tem a bola rolar: pastebin.com/zEE7B6d7
— Joseph Garvin

@JosephGarvin done!
— J David Smith

Esta solução funciona muito bem, mas eu também tinha que definir eshell-exit-hooka zero, porque isso automaticamente será carregado quando eshell começa: (add-hook 'eshell-exit-hook 'eshell-write-history nil t). Eu defini o gancho para ser localmente nulo dessa maneira (é globalmente nulo por padrão):(add-hook 'eshell-mode-hook '(lambda () (setq eshell-exit-hook nil)))
— GDP2 18/07/16
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.