Comment afficher un tampon d'aide / une fenêtre pleine taille (pas en plein écran)

8

Je souhaite parfois afficher des informations dans un style de tampon d'aide, j'ai donc utilisé du code comme celui-ci:

(with-help-window (help-buffer)
  (princ "Type q to exit this help buffer.\n\n")
  (princ result))

Cela fonctionne bien, mais la fenêtre d'aide n'utilise que la moitié de mon cadre. Je divise normalement mon cadre horizontalement, pour donner deux grandes fenêtres. Le tampon d'aide affiché utilise l'une des deux fenêtres.

Je préfère utiliser le cadre entier dans certains cas, pour afficher plus d'informations et pour réduire le nombre de fois que je dois parcourir les informations affichées. Le problème à résoudre est de savoir comment utiliser temporairement tout le cadre pour l' with-help-windowappel et restaurer automatiquement les tailles de tampons / fenêtres d'origine lorsque je tape "q" dans la fenêtre d'aide.

Comment puis-je atteindre au mieux cet objectif? Je pense que je cherche quelque chose comme ça:

(with-FULL-FRAME-help-window (help-buffer)
   ...)

J'ai regardé le mode gagnant, les signets, la sauvegarde des dispositions dans les registres, les différentes (display-buffer ...)méthodes (et puissantes, mais complexes) . La plupart d'entre eux semblent légèrement hors cible par rapport à mon intention, car ils ont tendance à corriger / restaurer une mise en page après une opération d'affichage plein cadre. Et il me semble que beaucoup d'entre eux me demandent de restaurer manuellement la disposition de ma fenêtre (ce que je préférerais ne pas faire).

Je me demande si quelqu'un a entendu parler d'un moyen de résoudre ce problème simplement. J'espère quelque chose de simple comme ces approches possibles, où je peux remplacer quelque chose avec un cadre let ...

(let ((help-window-width-display-option fullwidth))
  (with-help-window (help-buffer)
    ...))

Ou ce genre d'approche, que je ne sais pas encore faire, et qui semble quelque peu difficile / délicate pour mon niveau de compétence actuel.

(let ((save original configuration somehow)
  (delete-other-windows)
  (with-help-window (help-buffer)
     ...)
  ;; somehow, when I type "q" in the help buffer
  ;; - catch that action in code after the buffer is killed
  ;; - and restore the original window configuration
  )

Il me semble que le problème clé à résoudre est de savoir comment restaurer automatiquement la configuration de la fenêtre d'origine lorsque je tape "q" dans le tampon du mode d'aide temporaire. Merci

Kevin
la source
Une idée serait d'utiliser display-buffer-pop-up-frame: gnu.org/software/emacs/manual/html_node/elisp/… Une autre idée serait de lancer un make-frame tout en utilisant display-bufferune fonction personnalisée pour cibler ce nouveau cadre. Si vous souhaitez localiser et cibler un cadre existant, jetez un œil à cet exemple: stackoverflow.com/questions/18346785/…
lawlist
Voici une idée de la façon d'enregistrer et de restaurer la configuration de votre fenêtre afin que vous puissiez utiliser le cadre existant: emacs.stackexchange.com/a/2714/2287 Si vous trouvez que, comme certaines configurations de fenêtre, vous souhaiterez peut-être envisager de définir quelque chose qui est plus élaboré - il existe plusieurs bibliothèques qui traitent de la sauvegarde et de la commutation entre les différentes configurations de fenêtres.
lawlist
Comme d'habitude, merci pour votre aide. J'ai déjà essayé display-buffer-pop-up-frame, car c'est assez proche de ce que je recherche. Mais ... le cadre apparaît à un autre endroit (pas mon cadre actuel), et je dois le distribuer avec cmd-w, pas "q" dans le style d'aide. L'enregistrement / la restauration des configurations de fenêtre n'est pas le problème sous-jacent. Actuellement, je penche vers le clonage et la modification de la source de with-help-window pour lui donner une option que je peux laisser-lier ou boucler avec un defmacro ou quelque chose. Je souris à quel point nous émacions les gens à vouloir exactement ce que nous voulons d'Emacs.
Kevin
Après avoir lu plus dans help.el, la solution semble être enterrée quelque part dans help-return-method, quit-windowle quit-restoreparamètre de fenêtre, et probablement du code personnalisé pour définir / utiliser toutes ces choses pour créer l'effet souhaité.
Kevin

Réponses:

5

Exemple # 1 : Le raccourci clavier qdans le help-modetampon provient de celui special-mode-mapqui est incorporé dans le help-mode-map. La valeur par défaut est quit-window, qui n'offre que quatre (4) actions possibles: " Selon les informations stockées dans le quit-restoreparamètre de fenêtre de WINDOW, soit (1) supprimer WINDOW et son cadre, (2) supprimer WINDOW, (3) restaurer le tampon précédemment affiché dans WINDOW , ou (4) faire en sorte que WINDOW affiche un autre tampon que le tampon actuel. Si non nul, remettre le quit-restoreparamètre à zéro. "[Voir doc-string: M-x describe-function RET quit-window RET]

Voici un aperçu de ce que fait cet exemple:

  • Liez la variable help-window-selectà tpour que la *Help*fenêtre soit sélectionnée.

  • Liez la configuration actuelle de la fenêtre à une variable temporaire appelée config.

  • Générez la *Help*fenêtre.

  • Stockez la configuration de la fenêtre précédente - config- dans une variable locale appelée my-stored-win-config.

  • Créez une affectation de clé locale pour la lettre q, qui est liée à my-restore-win-config. [Cette affectation locale l'emporte / assombrit l'affectation précédente de quit-window.]

  • Supprimez les autres fenêtres.

  • Appuyez sur la lettre qpour restaurer la configuration de fenêtre précédente et tuer le *Help*tampon.

(defvar my-stored-win-config nil)
(make-variable-buffer-local 'my-stored-win-config)

(defun my-restore-win-config ()
  (interactive)
  (when my-stored-win-config
    (set-window-configuration my-stored-win-config)
    (kill-buffer "*Help*")))

L'extrait de code suivant est un exemple d'utilisation, mais n'est pas une fonction interactive complète. Il peut être évalué dans le *scratch*tampon pour le voir en action.

(let ((help-window-select t)
      (config (current-window-configuration)))
  (with-help-window (help-buffer)
    (princ "Type q to kill this *Help* buffer and restore prior window configuration."))
  (with-current-buffer "*Help*"
    (setq my-stored-win-config config)
    (local-set-key "q" 'my-restore-win-config))
  (delete-other-windows))

Exemple # 2 :

Voici une macro autonome qui fait tout comme l'exemple ci-dessus, qui traite de trois situations possibles liées aux valeurs de hook existantes - par exemple nil, symbole ou liste de symboles.

(defmacro help-window-full-frame (buffer-name &rest body)
"Doc-string."
  (declare (indent 1) (debug t))
  `(progn
    (set-marker help-window-point-marker nil)
      (let* (
          (help-window-select t)
          (foo
            (lambda ()
              (set (make-local-variable 'window-configuration)
                (current-window-configuration))
              (local-set-key "q"
                (lambda ()
                  (interactive)
                  (when window-configuration
                    ;; Record the `current-buffer' before it gets buried.
                    (let ((cb (current-buffer)))
                      (set-window-configuration window-configuration)
                      (kill-buffer cb)))))))
          ;; Preserve the original hook values by let-binding them in advance.
          ;; Otherwise, `add-to-list' would alter the global value.
          (temp-buffer-window-setup-hook temp-buffer-window-setup-hook)
          (temp-buffer-window-show-hook temp-buffer-window-show-hook)
          (temp-buffer-window-setup-hook
            (cond
              ((null temp-buffer-window-setup-hook)
                (list 'help-mode-setup foo))
              ((and
                  (not (null temp-buffer-window-setup-hook))
                  (listp temp-buffer-window-setup-hook))
                (add-to-list 'temp-buffer-window-setup-hook foo)
                (add-to-list 'temp-buffer-window-setup-hook 'help-mode-setup))
              ((and
                  (not (null temp-buffer-window-setup-hook))
                  (symbolp temp-buffer-window-setup-hook))
                (list 'help-mode-setup foo temp-buffer-window-setup-hook))))
          (temp-buffer-window-show-hook
            (cond
              ((null temp-buffer-window-show-hook)
                (list 'help-mode-finish 'delete-other-windows))
              ((and
                  (not (null temp-buffer-window-show-hook))
                  (listp temp-buffer-window-show-hook))
                (add-to-list 'temp-buffer-window-show-hook 'delete-other-windows)
                (add-to-list 'temp-buffer-window-show-hook 'help-mode-finish))
              ((and
                  (not (null temp-buffer-window-show-hook))
                  (symbolp temp-buffer-window-show-hook))
                (list
                  'help-mode-finish
                  'delete-other-windows
                  temp-buffer-window-show-hook)))) )
        (with-temp-buffer-window ,buffer-name nil 'help-window-setup (progn ,@body)))))

Et voici l'exemple d'extrait à évaluer dans le *scratch*tampon.

(help-window-full-frame (help-buffer)
  (princ "Type q to kill this *Help* buffer and restore prior window configuration."))
liste des lois
la source
Wow, merci pour une excellente réponse. J'avais progressé pour enregistrer / restaurer la configuration de la fenêtre, et j'avais créé une my-help-quitfonction, tout en essayant de relier la clé d'aide-carte à l'intérieur de with-help-window. Mais cela ne fonctionnait pas. Je vois maintenant que vous liez la clé à l'intérieur du tampon d' aide (pas la fenêtre d'aide comme je le faisais) après la configuration du tampon. Je suppose que ma liaison a été perturbée par la configuration du tampon. Une leçon apprise. Tout fonctionne maintenant. Merci beaucoup.
Kevin
Il y a deux (2) opportunités pour agir directement sur le *Help*tampon avant qu'il ne se termine - le temp-buffer-window-setup-hookqui s'exécute help-mode-setupet ensuite tout autre élément déjà / précédemment affecté au crochet; puis, le temp-buffer-window-show-hookqui s'exécute help-mode-finishet tout ce qui est déjà / précédemment affecté au crochet. help-mode-setupdevrait rester le premier dans le temps, mais vous pouvez ajouter quelque chose derrière en liant l'un de ces crochets susmentionnés avec des trucs personnalisés. Dans ce scénario, vous n'en auriez pas besoin with-current-buffer.
lawlist
D'accord. J'ai regardé les deux help-mode-setupet help-mode-finish, mais ils ont tous les deux fonctionné avant que le tampon ne soit affiché. Le problème clé était de rediriger la liaison de touches "q", et vous m'avez montré comment faire cela dans le tampon (pas dans la fenêtre, ce que j'essayais de faire). PS. J'ai essayé d'écrire une solution en tant que (defmacro with-full-frame-help-window, mais la macro nécessite toujours une fonction distincte pour gérer l'action "q" et la restauration de la fenêtre. Je posterai mes fonctions terminées ci-dessous.
Kevin
J'ai mis à jour la réponse avec un deuxième exemple qui utilise une macro autonome qui fait tout ce que fait le premier exemple.
lawlist
1
Cela fonctionne également pour moi, pour remplacer la référence de tampon " Aide " codée en dur au tampon actuel, car la restauration lambda est une fonction tampon locale. ... (kill-buffer (current-buffer)))))). La macro a pris un tampon-nom comme argument et a tué " Aide ", donc il pourrait y avoir un problème si l'appelant utilisait un tampon dont le nom était différent. J'ai modifié ma macro pour supprimer le buffer-nameparamètre et généré / tué le même tampon à l'intérieur du defmacro.
Kevin
3

Sur la base de l'excellente réponse de @lawlist, voici mes fonctions terminées pour le prochain gars ...

;; a tmp buffer-local place that gets destroyed with the help buffer
(defvar kwj-v-window-config-saved nil)
(make-variable-buffer-local 'kwj-v-window-config-saved)

(defun kwj-help-window-full-frame (string)
  "Show STRING in a help buffer using the full current frame."
  (let (original-layout)
    ;; set this before Help changes the config
    (setq original-layout (current-window-configuration))
    (with-help-window (help-buffer)
      (princ "Type q to exit this help buffer.\n\n")
      (princ string))
    (with-current-buffer "*Help*"
      ;; save layout in buffer local var that gets deleted
      (setq kwj-v-window-config-saved original-layout)
      ;; bind key in BUFFER (not in help window above)
      ;; bind key *after* help buf is displayed
      (local-set-key "q" 'kwj-help-window-restore))
    (delete-other-windows)))

(defun kwj-help-window-restore ()
  "Restore original windows after a full frame help display."
  (interactive)
  (set-window-configuration kwj-v-window-config-saved)
  (kill-buffer "*Help*"))

La longue chaîne de commentaires ci-dessus, avec l'aide continue de @lawlist, a abouti à cette version d'une macro qui ne nécessite pas de nom de tampon, traite correctement la configuration d'origine / affiche les listes de hooks, et cela ne pose pas de problème avec le "q "entrez d'autres tampons du mode Aide .

(defmacro with-help-window-full-frame (&rest body)
  "Display text in a full-frame help window.
Execute BODY forms to put output into the window, with standard
output directed to the buffer."
  ;;tell indenter about this macro name
  (declare (indent 1))
  ;; must use a buffer string name here, not the buffer itself
  `(let ((mybuf ,(buffer-name (get-buffer-create "Full Frame Help")))
         ;;`(let ((mybuf ,(help-buffer))
         mysetup tmpsetup tmpshow)
     ;; save a copy of original hooks
     (setq tmpsetup (copy-list temp-buffer-window-setup-hook))
     (setq tmpshow (copy-list temp-buffer-window-show-hook))

     ;; create window config store and restore functions
     ;; credit to @lawlist on stackoverflow for this embedded setup
     (setq mysetup
           (lambda ()
             ;; store original window configuration
             (set (make-local-variable 'orig-win-config)
                  (current-window-configuration))
             ;; bind q to the window restore function
             (local-set-key
              "q"
              (lambda ()
                (interactive)
                ;; q is shared by all Help-mode buffers
                ;; so guard those that did not set up orig-win-config
                (when (boundp 'orig-win-config)
                  (set-window-configuration orig-win-config))
                (kill-buffer (current-buffer))))))

     ;; Add to help setup hooks. Keep original hook functions if any
     ;; delete-dups destructively hacks our tmp copy, not original hooklists
     (push mysetup tmpsetup)          ;order critical here
     (push 'help-mode-setup tmpsetup) ;this must be first in hook
     (delete-dups tmpsetup)

     (push 'help-mode-finish tmpshow) ;order not important here
     (push 'delete-other-windows tmpshow)
     (delete-dups tmpshow)

     ;; shadow the original hooks with our copies for the display call
     (let ((temp-buffer-window-setup-hook tmpsetup)
           (temp-buffer-window-show-hook tmpshow))

       ;; show buf with locally embedded window restore function
       (with-temp-buffer-window mybuf nil
                                'help-window-setup
                                (progn ,@body)))))

Utilisez la macro de cette manière:

(with-help-window-full-frame
    (princ "Type q to exit this buffer."))
Kevin
la source