Unisci la cronologia da più eshells


9

Prima di passare a eshell avevo zsh setup in modo che potesse:

  • Scrivi nel file della cronologia dopo ogni comando
  • Aggiungi invece di sovrascrivere il file della cronologia, quindi quando eseguono più shell si unirebbero tutti in un'unica grande cronologia

Entrambe le opzioni zsh sono documentate qui (vedi APPEND_HISTORY e INC_APPEND_HISTORY).

Questo è molto utile se combinato con una cronologia di grandi dimensioni perché è possibile aprire una nuova shell settimane dopo aver emesso un comando e trovarlo nella cronologia (senza queste opzioni una cronologia di grandi dimensioni è inutile poiché conterrà solo la cronologia dell'ultimo chiuso conchiglia). Significa anche che puoi aprire nuove shell e far loro conoscere immediatamente i tuoi comandi più recenti in altre shell. Esiste un modo per configurare eshell con questo comportamento? Il primo proiettile sembra abbastanza facile ma accodare sembra più complicato ...

Risposte:


3

Disclaimer: non uso eshell, quindi prendilo con un po 'di sale.

eshellsembra chiamare eshell-write-historyper scrivere la cronologia, che accetta un argomento opzionale appendpredefinito nil. Questo argomento sembra essere eshellattualmente inutilizzato , ma sembra funzionare (passa l'argomento a write-region, che si aggiunge correttamente).

Ci sono un paio di opzioni qui.

  1. (setq eshell-save-history-on-exit nil)e chiamare eshell-write-historyte stesso
  2. Ridefinisci eshell-write-historyper soddisfare le tue esigenze.

Personalmente, andrei con 1.

Come esempio:

(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)

Grazie a @ joseph-garvin per la eshell-append-historyfunzione corretta e funzionante

Questo non gestisce il caricamento dinamico dei contenuti della nuova cronologia in una shell (ad es X. Esegui il comando nella shell A e visualizzalo nella cronologia nella shell B senza ricaricare; come SHARE_HISTORY di zsh). Non so quanto sia efficiente eshell-read-history, quindi sarei titubante nel farlo funzionare.

È anche possibile che tu finisca con voci duplicate con questa eshell-append-historyfunzione. Potrebbe essere necessario eseguire alcuni shenanigans cancellando tutto tranne la voce più recente eshell-history-ring, quindi ripristinandola al valore precedente dopo aver scritto la cronologia.

Per esempio

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

Grazie, sembra fantastico. Tuttavia, nel tuo primo frammento manca una citazione alla fine della docstring.
Joseph Garvin,

Ho dovuto modificarlo un po ', risulta che gli anelli devono essere modificati dalle funzioni ring- * o si verificano errori. Inoltre, utilizzo l'associazione dinamica per sostituire temporaneamente la definizione di eshell-history-ring invece di crearne una copia. Se inserisci il codice qui nella tua risposta, contrassegnerò come accettato poiché hai fatto rotolare la palla: pastebin.com/zEE7B6d7
Joseph Garvin,

@JosephGarvin fatto!
J David Smith,

Questa soluzione funziona benissimo, ma ho anche dovuto set eshell-exit-hooka zero, perché questo viene automaticamente caricato quando eshell comincia: (add-hook 'eshell-exit-hook 'eshell-write-history nil t). Ho impostato l'hook localmente zero in questo modo (è globalmente zero per impostazione predefinita):(add-hook 'eshell-mode-hook '(lambda () (setq eshell-exit-hook nil)))
GDP2
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.