Come visualizzare un buffer di aiuto / finestra a dimensione intera (non a schermo intero)


8

A volte desidero visualizzare le informazioni nello stile del buffer della Guida, quindi ho usato un codice come questo:

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

Funziona bene, ma la finestra di aiuto usa solo metà della mia cornice. Normalmente ho diviso il mio telaio in orizzontale, per dare due finestre alte. Il buffer della guida visualizzato utilizza una delle due finestre.

Preferirei utilizzare l'intero frame in alcuni casi, per visualizzare più informazioni e per ridurre il numero di volte in cui ho bisogno di scorrere le informazioni visualizzate. Il problema da risolvere è come utilizzare temporaneamente l'intero frame per la with-help-windowchiamata e ripristinare automaticamente le dimensioni dei buffer / finestre originali quando digito "q" nella finestra della guida.

Come posso raggiungere al meglio questo obiettivo? Penso di essere alla ricerca di qualcosa del genere:

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

Ho esaminato la modalità vincitore, i segnalibri, il salvataggio dei layout nei registri, i vari (e potenti, ma complessi) (display-buffer ...)metodi. La maggior parte di essi sembra leggermente fuori bersaglio rispetto al mio intento desiderato perché tendono a correggere / ripristinare un layout dopo un'operazione di visualizzazione a pieno formato. E mi sembra che molti di loro mi richiedano di ripristinare manualmente il layout della mia finestra (cosa che preferirei non fare).

Mi chiedo se qualcuno abbia sentito parlare di un modo per risolvere questo semplicemente. Spero in qualcosa di semplice come questi possibili approcci, in cui posso scavalcare qualcosa con un frame let ...

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

O questo tipo di approccio, che non so ancora come fare, e che sembra alquanto difficile / difficile per il mio attuale livello di abilità.

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

Mi sembra che il problema chiave da risolvere sia come ripristinare automaticamente la configurazione della finestra originale quando digito "q" nel buffer temporaneo della modalità di aiuto. Grazie


Un'idea sarebbe quella di usare display-buffer-pop-up-frame: gnu.org/software/emacs/manual/html_node/elisp/… Un'altra idea sarebbe quella di rilasciare un make-frame po 'di tempo usando display-bufferuna funzione personalizzata per indirizzare quel nuovo frame. Se siete interessati a localizzare e il targeting una cornice esistente, allora date un'occhiata a questo esempio: stackoverflow.com/questions/18346785/...
lawlist

Ecco un'idea di come salvare e ripristinare la configurazione della finestra in modo da poter utilizzare il frame esistente: emacs.stackexchange.com/a/2714/2287 Se lo trovi come alcune configurazioni di finestre, potresti prendere in considerazione l'idea di impostare qualcosa che è più elaborato - ci sono diverse librerie che si occupano del salvataggio e del passaggio tra le varie configurazioni della finestra.
elenco delle leggi del

Come al solito elenco delle leggi, grazie per il vostro aiuto. Ho già provato display-buffer-pop-up-frame, poiché è abbastanza vicino a quello che cerco. Ma ... il frame si apre in un altro posto (non il mio frame corrente), e devo inviarlo con cmd-w, non "q" in stile help. Il salvataggio / ripristino delle configurazioni della finestra non è il problema sottostante. Attualmente mi sto orientando verso la clonazione e la modifica della fonte di with-help-window per dargli un'opzione che posso lasciare legare, o concludere con un defmacro o qualcosa del genere. Sorrido a quanto schizzinosi siamo gli emacs che le persone vogliono esattamente ciò che vogliamo da Emacs.
Kevin,

Dopo aver letto di più in help.el, la soluzione sembra essere sepolta da qualche parte in help-return-method, quit-windowil quit-restoreparametro window e probabilmente un codice personalizzato per impostare / usare tutte quelle cose per creare l'effetto desiderato.
Kevin,

Risposte:


5

Esempio n. 1 : la scorciatoia da tastiera qnel help-modebuffer proviene da special-mode-mapquella incorporata nel file help-mode-map. Il valore predefinito è quit-window, che offre solo quattro (4) azioni possibili: " Secondo le informazioni memorizzate nel quit-restoreparametro della finestra di WINDOW (1) elimina WINDOW e il suo frame, (2) elimina WINDOW, (3) ripristina il buffer precedentemente visualizzato in WINDOW o (4) fare in modo che WINDOW visualizzi un buffer diverso da quello attuale. Se non nullo, reimpostare il quit-restoreparametro su zero. "[Vedi doc-string: M-x describe-function RET quit-window RET]

Ecco uno schema di ciò che fa questo esempio:

  • Associare la variabile help-window-selecta in tmodo che *Help*sia selezionata la finestra.

  • Associamo la configurazione della finestra corrente a una variabile temporanea chiamata config.

  • Genera la *Help*finestra.

  • Memorizza la configurazione della finestra precedente - config- in una variabile locale chiamata my-stored-win-config.

  • Creare un'assegnazione di chiave locale per la lettera q, a cui è associato my-restore-win-config. [Questo incarico locale supera / oscura il precedente incarico di quit-window.]

  • Elimina altre finestre.

  • Premere la lettera qper ripristinare la configurazione della finestra precedente ed eliminare il *Help*buffer.

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

Il frammento seguente è un esempio di utilizzo, ma non è una funzione interattiva completa. Può essere valutato nel *scratch*buffer per vederlo in azione.

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

Esempio n. 2 :

Ecco una macro indipendente che fa tutto come nell'esempio sopra, che tratta tre possibili situazioni relative ai valori di hook esistenti: ad esempio nil, simbolo o elenco di simboli.

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

Ed ecco lo snippet di esempio da valutare nel *scratch*buffer.

(help-window-full-frame (help-buffer)
  (princ "Type q to kill this *Help* buffer and restore prior window configuration."))

Wow, grazie per un'ottima risposta. Avevo progredito per salvare / ripristinare la configurazione della finestra e avevo creato una my-help-quitfunzione, mentre cercavo di ricollegare la chiave della mappa di aiuto all'interno di with-help-window. Ma non funzionava. Ora ti vedo associare la chiave all'interno del buffer della Guida (non la finestra della Guida come stavo facendo) dopo aver impostato il buffer. Immagino che la mia associazione sia stata ostruita dalla configurazione del buffer. Una lezione imparata. Ora funziona tutto. Grazie molto.
Kevin,

Ci sono due (2) opportunità di agire direttamente sul *Help*buffer prima che finisca: quello temp-buffer-window-setup-hookche viene eseguito help-mode-setupe quindi qualsiasi altra cosa già / precedentemente assegnata all'hook; e, quindi, temp-buffer-window-show-hookquale viene eseguito help-mode-finishe qualsiasi cosa già / precedentemente assegnata all'hook. help-mode-setupdovrebbe rimanere per primo in tempo, ma è possibile aggiungere qualcosa dietro vincolando uno di quei ganci di cui sopra con elementi personalizzati. In quello scenario, non avresti bisogno with-current-buffer.
elenco delle leggi del

Concordato. Ho guardato entrambi help-mode-setupe help-mode-finish, ma entrambi sono stati eseguiti prima della visualizzazione del buffer. Il problema chiave era reindirizzare il keybinding "q" e mi hai mostrato come farlo nel buffer (non nella finestra, che stavo cercando di fare). PS. Ho provato a scrivere una soluzione come (defmacro with-full-frame-help-window, ma la macro richiede ancora una funzione separata per gestire l'azione "q" e il ripristino della finestra. Pubblicherò di seguito le mie funzioni completate.
Kevin,

Ho aggiornato la risposta con un secondo esempio che utilizza una macro indipendente che fa tutto ciò che fa il primo esempio.
elenco delle leggi

1
Questo funziona anche per me, per sostituire il riferimento del buffer " Help " codificato al buffer corrente, poiché il ripristino lambda è una funzione buffer-local. ... (kill-buffer (current-buffer)))))). La macro ha preso un nome buffer come argomento e ha ucciso " Help ", quindi potrebbe esserci un problema se il chiamante utilizzava un buffer il cui nome era diverso. Ho modificato la mia macro per rimuovere il buffer-nameparametro e generato / ucciso lo stesso buffer all'interno del defmacro.
Kevin,

3

Sulla base dell'ottima risposta di @lawlist, ecco le mie funzioni completate per il prossimo ragazzo ...

;; 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 lunga catena di commenti sopra, con il continuo aiuto di @lawlist, ha portato a questa versione di una macro che non richiede un nome di buffer, tratta correttamente la configurazione originale / mostra gli hook list e che non causa problemi con "q "digitare in altri buffer della modalità di aiuto .

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

Usa la macro in questo modo:

(with-help-window-full-frame
    (princ "Type q to exit this buffer."))
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.