Fusionner l'historique de plusieurs eshells

9

Avant de passer à eshell, j'avais configuré zsh pour qu'il:

  • Écrire dans le fichier historique après chaque commande
  • Ajoutez plutôt que remplacez le fichier d'historique, donc lors de l'exécution de plusieurs shells, ils seraient tous fusionnés en un seul gros historique

Les deux options zsh sont documentées ici (voir APPEND_HISTORY et INC_APPEND_HISTORY).

Ceci est super utile lorsqu'il est combiné avec une grande taille d'historique, car vous pouvez ouvrir un nouveau shell des semaines après avoir émis une commande et le trouver dans votre historique (sans ces options, un grand historique est inutile car il ne contiendra que l'historique du dernier fermé coquille). Cela signifie également que vous pouvez ouvrir de nouveaux shells et leur faire connaître immédiatement vos commandes les plus récentes dans d'autres shells. Existe-t-il un moyen de configurer eshell avec ce comportement? La première puce semble assez facile mais l'ajout semble plus délicat ...

Joseph Garvin
la source

Réponses:

3

Avis de non-responsabilité: je n'utilise pas de coquille, alors prenez-le avec un grain de sel.

eshellsemble appeler eshell-write-historypour écrire l'historique, qui prend un argument facultatif appendqui est par défaut nil. Cet argument semble être inutilisé eshellactuellement, mais semble fonctionner (il transmet l'argument à write-region, qui s'ajoute correctement).

Il y a quelques options ici.

  1. (setq eshell-save-history-on-exit nil)et appelez- eshell-write-historyvous
  2. Redéfinissez eshell-write-historypour satisfaire votre exigence.

Personnellement, j'irais avec 1.

Par exemple:

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

Merci à @ joseph-garvin pour la eshell-append-historyfonction de travail corrigée

Cela ne gère pas le chargement dynamique du nouveau contenu de l'historique dans un shell (par exemple, exécuter la commande Xdans le shell A et le faire apparaître dans l'historique dans le shell B sans rechargement; comme SHARE_HISTORY de zsh). Je ne sais pas à quel point c'est efficace eshell-read-history, donc j'hésiterais à le lancer dans un crochet.

Il est également possible que vous vous retrouviez avec des entrées en double avec cette eshell-append-historyfonction. Vous devrez peut-être effectuer quelques manigances en effaçant toutes les entrées sauf la plus récente eshell-history-ring, puis en les réinitialisant à l'ancienne valeur après avoir écrit l'historique.

Par exemple

(let ((old-ring (copy-list eshell-history-ring)))
  (setq eshell-history-ring (list (car eshell-history-ring)))
  ; write
  (setq eshell-history-ring old-ring))
J David Smith
la source
Merci, ça a l'air génial. Cependant, votre premier extrait de code manque une citation à la fin de la docstring.
Joseph Garvin
J'ai dû le modifier, il s'avère que les anneaux doivent être modifiés par les fonctions ring- * ou vous rencontrez des erreurs. J'utilise également la liaison dynamique pour remplacer temporairement la définition de eshell-history-ring au lieu de faire une copie. Si vous mettez le code ici dans votre réponse, je marquerai comme accepté depuis que vous avez lancé la balle: pastebin.com/zEE7B6d7
Joseph Garvin
@JosephGarvin fait!
J David Smith
Cette solution fonctionne très bien, mais je devais aussi mettre eshell-exit-hookà zéro parce que cela est automatiquement chargé lorsque eshell commence: (add-hook 'eshell-exit-hook 'eshell-write-history nil t). Je mets le crochet localement à zéro comme ça (il est globalement nul par défaut):(add-hook 'eshell-mode-hook '(lambda () (setq eshell-exit-hook nil)))
GDP2