Cara menampilkan bantuan buffer / jendela ukuran bingkai penuh (bukan layar penuh)

8

Saya terkadang ingin menampilkan informasi dalam gaya buffer Bantuan, jadi saya telah menggunakan kode seperti ini:

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

Ini berfungsi dengan baik, tetapi jendela bantuan hanya menggunakan setengah dari bingkai saya. Saya biasanya membagi bingkai saya secara horizontal, untuk memberikan dua jendela tinggi. Buffer bantuan yang ditampilkan menggunakan salah satu dari dua jendela.

Saya lebih suka menggunakan seluruh frame dalam beberapa kasus, untuk menampilkan lebih banyak informasi dan untuk mengurangi berapa kali saya perlu menelusuri informasi yang ditampilkan. Masalah yang harus dipecahkan adalah bagaimana untuk sementara waktu menggunakan seluruh frame untuk with-help-windowpanggilan, dan untuk secara otomatis mengembalikan buffer / ukuran jendela ketika saya mengetik "q" di jendela bantuan.

Bagaimana cara terbaik untuk mencapai tujuan ini? Saya pikir saya sedang mencari sesuatu seperti ini:

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

Saya telah melihat mode pemenang, bookmark, menyimpan tata letak ke register, berbagai metode (dan kuat, tetapi kompleks) (display-buffer ...). Sebagian besar dari mereka tampaknya sedikit tidak sesuai dengan maksud yang saya inginkan karena mereka cenderung untuk memperbaiki / mengembalikan tata letak setelah operasi tampilan bingkai penuh. Dan menurut saya banyak dari mereka mengharuskan saya untuk secara manual mengembalikan tata letak jendela saya (yang saya lebih suka tidak melakukannya).

Saya bertanya-tanya apakah ada yang pernah mendengar cara untuk menyelesaikan ini dengan mudah. Saya berharap sesuatu yang sederhana seperti pendekatan yang mungkin ini, di mana saya dapat menimpa sesuatu dengan bingkai let ...

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

Atau pendekatan semacam ini, yang saya belum tahu bagaimana melakukannya, dan yang terlihat agak sulit / rumit untuk tingkat keterampilan saya saat ini.

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

Menurut saya masalah utama yang harus saya selesaikan adalah bagaimana mengembalikan secara otomatis konfigurasi jendela asli ketika saya mengetik "q" di buffer mode bantuan sementara. Terima kasih

Kevin
sumber
Satu ide adalah menggunakan display-buffer-pop-up-frame: gnu.org/software/emacs/manual/html_node/elisp/... Gagasan ide lainnya adalah mengeluarkan make-frame sementara menggunakan display-bufferfungsi khusus untuk menargetkan frame baru itu. Jika Anda tertarik untuk mencari dan menargetkan bingkai yang ada, maka lihat contoh ini: stackoverflow.com/questions/18346785/…
lawlist
Berikut ini adalah ide bagaimana cara menyimpan dan mengembalikan konfigurasi jendela Anda sehingga Anda dapat menggunakan bingkai yang ada: emacs.stackexchange.com/a/2714/2287 Jika Anda menemukan itu seperti konfigurasi jendela tertentu, Anda mungkin ingin mempertimbangkan untuk mengatur sesuatu Facebook yang lebih rumit - ada beberapa perpustakaan yang berurusan dengan menyimpan dan beralih di antara berbagai konfigurasi jendela.
hukum
Seperti daftar biasa, terima kasih atas bantuan Anda. Saya sudah mencoba display-buffer-pop-up-frame, karena cukup dekat dengan apa yang saya cari. Tapi ... frame muncul di tempat lain (bukan frame saya saat ini), dan saya harus mengirimnya dengan cmd-w, bukan "q" dengan gaya bantuan. Menyimpan / mengembalikan konfigurasi jendela bukanlah masalah yang mendasarinya. Saat ini saya condong ke arah kloning dan memodifikasi sumber dengan-bantuan-jendela untuk memberikan opsi yang saya bisa ikat, atau bungkus dengan defmacro atau sesuatu. Saya tersenyum melihat betapa pemilih kami emacs orang pada keinginan persis apa yang kita inginkan dari Emacs.
Kevin
Setelah membaca lebih banyak di help.el, solusinya tampaknya terkubur di suatu tempat di help-return-method, quit-window, yang quit-restoreparameter jendela, dan mungkin beberapa kode kustom untuk set / menggunakan semua hal-hal untuk menciptakan efek yang diinginkan.
Kevin

Jawaban:

5

Contoh # 1 : Pintasan keyboard qdi help-modebuffer berasal dari special-mode-mapyang dimasukkan ke dalam help-mode-map. Nilai defaultnya adalah quit-window, yang hanya menawarkan empat (4) tindakan yang mungkin: " Menurut informasi yang disimpan dalam quit-restoreparameter jendela WINDOW (1) hapus WINDOW dan bingkainya, (2) hapus WINDOW, (3) pulihkan buffer yang sebelumnya ditampilkan dalam WINDOW , atau (4) membuat WINDOW menampilkan beberapa buffer lain dari yang sekarang. Jika non-nil, atur ulang quit-restoreparameter ke nil. "[Lihat doc-string: M-x describe-function RET quit-window RET]

Berikut adalah garis besar dari apa yang dilakukan contoh ini:

  • Mari-mengikat variabel help-window-selectke tsehingga *Help*jendela yang dipilih.

  • Biarkan-ikat konfigurasi jendela saat ini ke variabel sementara bernama config.

  • Buat *Help*jendela.

  • Simpan konfigurasi jendela sebelumnya - config- dalam variabel lokal bernama my-stored-win-config.

  • Buat tugas kunci lokal untuk surat q, yang terikat my-restore-win-config. [Tugas lokal ini mengalahkan / membayangi tugas sebelumnya dari quit-window.]

  • Hapus jendela lain.

  • Tekan huruf quntuk mengembalikan konfigurasi jendela sebelumnya, dan bunuh *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*")))

Cuplikan berikut adalah contoh penggunaan, tetapi bukan fungsi interaktif yang lengkap. Itu dapat dievaluasi dalam *scratch*buffer untuk melihatnya beraksi.

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

Contoh # 2 :

Berikut ini adalah makro mandiri yang melakukan semuanya seperti contoh di atas, yang berkaitan dengan tiga situasi yang mungkin berkaitan dengan nilai kait yang ada - misalnya nil,, simbol, atau, daftar simbol.

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

Dan di sini adalah cuplikan sampel untuk dievaluasi dalam *scratch*buffer.

(help-window-full-frame (help-buffer)
  (princ "Type q to kill this *Help* buffer and restore prior window configuration."))
daftar hukum
sumber
Wow, terima kasih atas jawaban yang bagus. Saya telah maju untuk menyimpan / mengembalikan konfigurasi jendela, dan telah membuat my-help-quitfungsi, ketika mencoba untuk memutar kembali kunci peta bantuan di dalam with-help-window. Tapi itu tidak berhasil. Saya sekarang melihat Anda mengikat kunci di dalam buffer Bantuan (bukan jendela Bantuan seperti yang saya lakukan) setelah buffer diatur. Saya kira mengikat saya musnah oleh setup buffer. Pelajaran yang bisa dipetik. Semuanya berfungsi sekarang. Terimakasih banyak.
Kevin
Ada dua (2) peluang untuk bertindak langsung pada *Help*buffer sebelum selesai - temp-buffer-window-setup-hookyang berjalan help-mode-setupdan kemudian hal lain yang sudah / sebelumnya ditugaskan ke hook; dan, kemudian temp-buffer-window-show-hookyang berjalan help-mode-finishdan apa pun yang sudah / sebelumnya ditugaskan ke hook. help-mode-setupharus tetap pertama kali, tetapi Anda dapat menambahkan sesuatu di belakangnya dengan mengikat salah satu kait tersebut dengan barang-barang khusus. Dalam skenario itu, Anda tidak perlu with-current-buffer.
lawlist
Sepakat. Saya melihat keduanya help-mode-setupdan help-mode-finish, tetapi mereka berdua berlari sebelum buffer ditampilkan. Masalah utama adalah untuk mengarahkan kembali "q" keybinding, dan Anda menunjukkan kepada saya bagaimana melakukannya di buffer (bukan jendela, yang saya coba lakukan). PS. Saya mencoba menulis solusi sebagai (defmacro with-full-frame-help-window, tetapi makro masih memerlukan fungsi terpisah untuk menangani "q" dan tindakan restorasi jendela. Saya akan memposting fungsi selesai saya di bawah ini.
Kevin
Saya memperbarui jawaban dengan contoh kedua yang menggunakan makro mandiri yang melakukan semua yang dilakukan contoh pertama.
hukum
1
Ini juga berfungsi untuk saya, untuk mengganti referensi buffer " Bantuan " hardcoded ke buffer saat ini, karena restorasi lambda adalah fungsi buffer-local. ... (kill-buffer (current-buffer)))))). Makro mengambil nama penyangga sebagai argumen, dan membunuh " Bantuan ", jadi mungkin ada masalah jika penelepon menggunakan penyangga yang namanya berbeda. Saya memodifikasi makro saya untuk menghapus buffer-nameparameter, dan menghasilkan / membunuh buffer yang sama di dalam defmacro.
Kevin
3

Berdasarkan jawaban yang sangat baik dari @lawlist, berikut adalah fungsi saya yang sudah selesai untuk orang berikutnya ...

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

Rantai panjang komentar di atas, dengan bantuan terus-menerus dari @lawlist, menghasilkan versi makro ini yang tidak memerlukan nama penyangga, memperlakukan dengan benar pengaturan / daftar kait acara yang ditampilkan, dan itu tidak menyebabkan masalah dengan "q " masukkan buffer mode Bantuan lainnya .

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

Gunakan makro dengan cara ini:

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