So zeigen Sie einen Hilfepuffer / ein Fenster in voller Bildgröße an (nicht im Vollbildmodus)

8

Ich möchte manchmal Informationen im Hilfepufferstil anzeigen, daher habe ich folgenden Code verwendet:

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

Dies funktioniert gut, aber das Hilfefenster verwendet nur die Hälfte meines Frames. Normalerweise teile ich meinen Rahmen horizontal, um zwei hohe Fenster zu erhalten. Der angezeigte Hilfepuffer verwendet eines der beiden Fenster.

In einigen Fällen würde ich lieber den gesamten Frame verwenden, um mehr Informationen anzuzeigen und die Häufigkeit zu verringern, mit der ich die angezeigten Informationen durchblättern muss. Das zu lösende Problem besteht darin, den gesamten Frame vorübergehend für den with-help-windowAufruf zu verwenden und die ursprünglichen Puffer / Fenstergrößen automatisch wiederherzustellen, wenn ich im Hilfefenster "q" eingebe.

Wie kann ich dieses Ziel am besten erreichen? Ich glaube, ich suche so etwas:

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

Ich habe mir den Winner-Modus, Lesezeichen, das Speichern von Layouts in Registern und die verschiedenen (und leistungsstarken, aber komplexen) (display-buffer ...)Methoden angesehen. Die meisten von ihnen scheinen meiner gewünschten Absicht etwas zuwider zu sein, da sie dazu neigen, ein Layout nach einem Vollbild-Anzeigevorgang zu korrigieren / wiederherzustellen. Und es scheint mir, dass viele von ihnen erfordern, dass ich mein Fensterlayout manuell wiederherstelle (was ich lieber nicht tun würde).

Ich frage mich, ob jemand von einem Weg gehört hat, dies einfach zu lösen. Ich hoffe auf etwas Einfaches wie diese möglichen Ansätze, bei denen ich etwas mit einem Let-Frame überschreiben kann ...

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

Oder diese Art von Ansatz, den ich noch nicht beherrsche und der für mein aktuelles Können etwas schwierig / knifflig aussieht.

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

Es scheint mir, dass das Hauptproblem, das ich lösen muss, darin besteht, die ursprüngliche Fensterkonfiguration automatisch wiederherzustellen, wenn ich "q" in den temporären Hilfemodus-Puffer eingebe. Vielen Dank

Kevin
quelle
Eine Idee wäre zu nützen display-buffer-pop-up-frame: gnu.org/software/emacs/manual/html_node/elisp/... Eine weitere Idee Idee wäre ein zu erteilen , make-frame während Verwendung display-buffermit einer benutzerdefinierten Funktion , um diesen neuen Rahmen Ziel. Wenn Sie daran interessiert sind, einen vorhandenen Frame zu finden und auf ihn abzuzielen,
lawlist
Hier ist eine Idee, wie Sie Ihre Fensterkonfiguration speichern und wiederherstellen können, damit Sie den vorhandenen Frame verwenden können: emacs.stackexchange.com/a/2714/2287 Wenn Sie dies wie bestimmte Fensterkonfigurationen finden, sollten Sie möglicherweise etwas festlegen Das ist aufwändiger - es gibt mehrere Bibliotheken, die sich mit dem Speichern und Umschalten zwischen verschiedenen Fensterkonfigurationen befassen.
Lawlist
Vielen Dank für Ihre Hilfe. Ich habe es bereits versucht display-buffer-pop-up-frame, da es ziemlich nahe an dem liegt, was ich suche. Aber ... der Frame erscheint an einer anderen Stelle (nicht in meinem aktuellen Frame), und ich muss ihn mit cmd-w versenden, nicht mit "q" im Hilfestil. Das Speichern / Wiederherstellen von Fensterkonfigurationen ist nicht das zugrunde liegende Problem. Derzeit neige ich dazu, die Quelle des With-Help-Fensters zu klonen und zu ändern, um ihr eine Option zu geben, die ich binden oder mit einem Defmacro oder etwas anderem umschließen kann. Ich lächle darüber, wie wählerisch wir Emacs sind, wenn es darum geht , genau das zu wollen , was wir von Emacs wollen.
Kevin
Nach der Lektüre mehr in help.el scheint die Lösung irgendwo in begraben zu werden help-return-method, quit-windowdie quit-restoreFensterparameter, und wahrscheinlich einige benutzerdefinierte Code zu setzen / alle diese Dinge verwenden , um die gewünschten Effekte zu erzeugen.
Kevin

Antworten:

5

Beispiel 1 : Die Tastenkombination qim help-modePuffer stammt von der special-mode-map, die in die integriert ist help-mode-map. Der Standardwert ist quit-window, der nur vier (4) mögliche Aktionen bietet: " Gemäß den im Fensterparameter von WINDOW gespeicherten Informationen quit-restorelöschen Sie entweder (1) WINDOW und seinen Frame, (2) löschen Sie WINDOW, (3) stellen Sie den zuvor in WINDOW angezeigten Puffer wieder her , oder (4) lassen Sie WINDOW einen anderen Puffer als den aktuellen anzeigen. Wenn nicht Null, setzen Sie den quit-restoreParameter auf Null zurück. "[Siehe doc-string: M-x describe-function RET quit-window RET]

Hier ist ein Überblick über die Funktionsweise dieses Beispiels:

  • Binden Sie die Variable help-window-selectan, tdamit das *Help*Fenster ausgewählt wird.

  • Binden Sie die aktuelle Fensterkonfiguration an eine temporäre Variable namens config.

  • Generieren Sie das *Help*Fenster.

  • Speichern Sie die vorherige Fensterkonfiguration - config- in einer lokalen Variablen namens my-stored-win-config.

  • Erstellen Sie eine lokale Schlüsselzuweisung für den Buchstaben q, an den gebunden ist my-restore-win-config. [Diese lokale Zuordnung übertrumpft / beschattet die vorherige Zuweisung von quit-window.]

  • Löschen Sie andere Fenster.

  • Drücken Sie den Buchstaben q, um die vorherige Fensterkonfiguration wiederherzustellen, und beenden Sie den *Help*Puffer.

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

Das folgende Snippet ist eine Beispielverwendung, jedoch keine vollständige interaktive Funktion. Es kann im *scratch*Puffer ausgewertet werden , um es in Aktion zu sehen.

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

Beispiel 2 :

Hier ist ein in sich geschlossenes Makro, das alles wie im obigen Beispiel ausführt und drei mögliche Situationen in Bezug auf vorhandene Hook-Werte behandelt - z. B. nilSymbol oder Liste von Symbolen.

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

Und hier ist das Beispiel-Snippet, das im *scratch*Puffer ausgewertet werden soll .

(help-window-full-frame (help-buffer)
  (princ "Type q to kill this *Help* buffer and restore prior window configuration."))
Gesetzesliste
quelle
Wow, danke für eine hervorragende Antwort. Ich war mit dem Speichern / Wiederherstellen der Fensterkonfiguration fortgefahren und hatte eine my-help-quitFunktion erstellt, während ich versuchte, den Help-Map-Schlüssel innerhalb von neu zu binden with-help-window. Aber es hat nicht funktioniert. Ich sehe dich jetzt binden Sie den Schlüssel in dem Help - Puffer (nicht das Hilfefenster wie ich tat) , nachdem der Puffer eingerichtet ist. Ich denke, meine Bindung wurde durch das Puffer-Setup blockiert. Eine Lektion gelernt. Alles funktioniert jetzt. Danke vielmals.
Kevin
Es gibt zwei (2) Möglichkeiten, direkt auf den *Help*Puffer zu reagieren, bevor dieser beendet ist - die, temp-buffer-window-setup-hookdie ausgeführt wird, help-mode-setupund dann alles andere, was dem Hook bereits / zuvor zugewiesen wurde; und dann das temp-buffer-window-show-hookwas läuft help-mode-finishund alles was schon / vorher dem hook zugeordnet ist. help-mode-setupsollte zuerst in der Zeit bleiben, aber Sie könnten etwas dahinter hinzufügen, indem Sie einen der oben genannten Haken mit benutzerdefinierten Sachen binden. In diesem Szenario würden Sie nicht benötigen with-current-buffer.
Lawlist
Einverstanden. Ich sah beide an help-mode-setupund help-mode-finish, aber beide liefen, bevor der Puffer angezeigt wurde. Das Hauptproblem bestand darin, die Tastenkombination "q" umzuleiten, und Sie haben mir gezeigt, wie das im Puffer funktioniert (nicht im Fenster, was ich versucht habe). PS. Ich habe versucht, eine Lösung als zu schreiben (defmacro with-full-frame-help-window, aber das Makro benötigt immer noch eine separate Funktion, um die Aktion "q" und die Fensterwiederherstellung durchzuführen. Ich werde meine abgeschlossenen Funktionen unten veröffentlichen.
Kevin
Ich habe die Antwort mit einem zweiten Beispiel aktualisiert, das ein in sich geschlossenes Makro verwendet, das alles tut, was das erste Beispiel tut.
Lawlist
1
Dies funktioniert auch bei mir, um die fest codierte " Hilfe " -Pufferreferenz auf den aktuellen Puffer zu ersetzen , da das Wiederherstellungs-Lambda eine pufferlokale Funktion ist. ... (kill-buffer (current-buffer)))))). Das Makro hat einen Puffernamen als Argument verwendet und " Help " beendet, sodass ein Problem auftreten kann, wenn der Aufrufer einen Puffer verwendet, dessen Name unterschiedlich ist. Ich habe mein Makro geändert, um den buffer-nameParameter zu entfernen , und denselben Puffer im defmacro generiert / beendet.
Kevin
3

Basierend auf der hervorragenden Antwort von @lawlist sind hier meine abgeschlossenen Funktionen für den nächsten Mann ...

;; 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*"))

Die lange Kette von Kommentaren oben führte mit fortgesetzter Hilfe von @lawlist zu dieser Version eines Makros, das keinen Puffernamen benötigt, die ursprünglichen Setup- / Show-Hook-Listen ordnungsgemäß behandelt und keine Probleme mit dem "q" verursacht "Taste in anderen Help - Modus Puffer.

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

Verwenden Sie das Makro folgendermaßen:

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