Minacuffer içeriği emacs çerçevesinin ortasında nasıl görüntülenir?


20

Maksimize edilmiş bir Emacs çerçevesi üzerinde çalışırken, ekranın altında minibuffer / eko alanı içeriğinin görüntülenmesi zor olabilir, ancak aynı zamanda bir komut yazarken düzenlenen metne odaklanmayı kaybetmeye neden olur - bu oldukça kullanılabilirlik açısından.

Minibuffer / echo alanını geçerli emacs tamponunun ortasına, minibuffer aktifken düzenlenen metnin üzerine taşımanın veya daha iyi, minibuffer içeriğini yakalayıp merkezde görüntülemenin bir yolu var mı komutunu yazarken geçerli arabellek?


Tamlık için, bu kullanılabilirlik sorununa şu anki çözümümün minibuffer'ın yazı tipi boyutunu artırmak olduğunu eklemeliyim, ancak maksimize edilmemiş karelerde aptalca görünüyor.
Sébastien Le Callonnec

Yanıtlar:


10

Merkezde Popup Minibuffer

İşte tam olarak sorduğunuz şeyi yapmanın bir yolu: minibuffer'ı ekranın ortasında görüntüleyin .

  1. Minibuffer için ayrı bir çerçeve bulundurun
  2. Merkeze yerleştirin
  3. Minibuffer odaklandığında bu kareyi kaldırın.

Bunu başarmak nispeten kolaydır ve oneonone.elpaketle elde edeceğiniz şey budur (@Drew'un işaret ettiği gibi). Bu yaklaşımdaki sorun, minibuffer'ın mesajlar için de kullanılmasıdır, bu yüzden gizli tutulması çok uygun bir şey değildir. Endişe etmeyin! Başka bir çözüm buldum.

  1. Bir var ikinci minibuffer ayrı çerçeve üzerinde gösterdi.
  2. Ortaya yerleştirin.
  3. Etkileşimli komutlar için ikinci çerçeveyi kullanırken, iletilerin yankılanması için orijinal (ilk) minibuffer kullanılır.

uygulama

Bunu uygulamak için emacs başlangıcında minibuffer çerçevesi oluşturmamız gerekiyor.

(defvar endless/popup-frame-parameters
  '((name . "MINIBUFFER")
    (minibuffer . only)
    (height . 1)
    ;; Ajust this one to your preference.
    (top . 200))
  "Parameters for the minibuffer popup frame.")

(defvar endless/minibuffer-frame
  (let ((mf (make-frame endless/popup-frame-parameters)))
    (iconify-frame mf) mf)
  "Frame holding the extra minibuffer.")

(defvar endless/minibuffer-window
  (car (window-list endless/minibuffer-frame t))
  "")

Ardından read-from-minibufferorijinal çerçevenin minibuffer'ı yerine bu ikinci minibufferi kullanmak için yama yapıyoruz .

(defmacro with-popup-minibuffer (&rest body)
  "Execute BODY using a popup minibuffer."
  (let ((frame-symbol (make-symbol "selected-frame")))
    `(let* ((,frame-symbol (selected-frame)))
       (unwind-protect 
           (progn 
             (make-frame-visible endless/minibuffer-frame)
             (when (fboundp 'point-screen-height)
               (set-frame-parameter
                endless/minibuffer-frame 
                'top (point-screen-height)))
             (select-frame-set-input-focus endless/minibuffer-frame 'norecord)
             ,@body)
         (select-frame-set-input-focus ,frame-symbol)))))

(defun use-popup-minibuffer (function)
  "Rebind FUNCTION so that it uses a popup minibuffer."
  (let* ((back-symb (intern (format "endless/backup-%s" function)))
         (func-symb (intern (format "endless/%s-with-popup-minibuffer"
                                    function)))
         (defs `(progn
                  (defvar ,back-symb (symbol-function ',function))
                  (defun ,func-symb (&rest rest)
                    ,(format "Call `%s' with a poupup minibuffer." function)
                    ,@(list (interactive-form function))
                    (with-popup-minibuffer 
                     (apply ,back-symb rest))))))
    (message "%s" defs)
    (when (and (boundp back-symb) (eval back-symb))
      (error "`%s' already defined! Can't override twice" back-symb))
    (eval defs)
    (setf (symbol-function function) func-symb)))

;;; Try at own risk.
(use-popup-minibuffer 'read-from-minibuffer)
;;; This will revert the effect.
;; (setf (symbol-function #'read-from-minibuffer) endless/backup-read-from-minibuffer)
;; (setq endless/backup-read-from-minibuffer nil)

Bu kesinlikle her şeyi ile çalışmayabilir, ama şimdiye kadar denedim her konuda çalışmış --- find-file, ido-switch-buffer, eval-expression. Eğer varsa yapmak herhangi istisnalar bul, çağırarak bir vaka ile ayrı ayrı bu işlevleri yama olabilir use-popup-minibufferonlara.

Konum Yakın Nokta

Bu minibuffer çerçevesini noktanın yüksekliğine yakın bir yere yerleştirmek için aşağıdaki işlev gibi bir şey tanımlamanız yeterlidir. Mükemmel değil (aslında, birçok durumda korkunç), ancak nokta yüksekliğini tahmin etmek için iyi bir iş çıkarıyor.

(defun point-screen-height ()
  (* (/ (face-attribute 'default :height) 10) 2
     (- (line-number-at-pos (point))
        (line-number-at-pos (window-start)))))

İle uğraşmak yerine (veya daha eski ) (setf (symbol-function function) ...)kullanarak daha iyi olurdu . advice-addad-add-advice
Stefan

6

Üstte minibuffer

Minibuffer'ın ekranın ortasında gösterilmesi karmaşıktır. Makul bir alternatif (daha okunaklı bulabileceğiniz veya bulamayacağınız) üste taşımaktır.

Çerçevenin minibuffer'ının konumunu (veya varlığını) değişken içindeki minibufferframe parametresi ile yapılandırabilirsiniz initial-frame-alist.

Ayrı Çerçeve

Parametrenin ayarlanması nilçerçeveyi minibuffer içermeyecek şekilde yapılandırır ve Emacs sizin için otomatik olarak ayrı bir minibuffer çerçevesi oluşturur. Bu iki kareyi işletim sisteminizin pencere yöneticisini kullanarak konumlandırabilir veya Emacs'tan yapabilirsiniz.

Aşağıdaki snippet, minibuffer çerçevesinin en üste nasıl yerleştirileceğini, normal çerçevenin hemen altında olacak şekilde örnekliyor, ancak monitör boyutunu hesaba katmak için sayıları kesinlikle değiştirmeniz gerekecek.

(setq initial-frame-alist
      '((left . 1) (minibuffer . nil)
        ;; You'll need to adjust the following 3 numbers.
        (top . 75) ; In pixels
        (width . 127) ; In chars
        (height . 31)))

(setq minibuffer-frame-alist
      '((top . 1) (left . 1) (height . 2)
        ;; You'll need to adjust the following number.
        (width . 127)))

Bunu ayarlamanın en hızlı yolu pencere yöneticinizdeki kareleri yeniden boyutlandırmak ve sonra (frame-parameters)sahip olduğunuz parametre değerlerini görmek için değerlendirmektir .

Aynı Çerçeve

Başka bir olasılık, minibufferparametreyi bir pencereye ayarlamaktır . Ne yazık ki, bunu aynı çerçevedeki bir pencere için çalıştıramadım.


5

Kütüphane oneonone.elbunu kutudan çıkarır.

Sadece seçeneği 1on1-minibuffer-frame-top/bottombağımsız minibuffer çerçevesi için istediğiniz konuma özelleştirin . Değer, ekranınızın üstünden (negatif değilse) veya altından (negatifse) piksel sayısıdır. Örneğin, dikey olarak ortalamak için değeri görüntüleme yüksekliğinize bölünerek 2'ye ayarlayın.

Bunun yerine dinamik olarak konumlandırılmasını istiyorsanız, geçerli çerçevenin dikey merkezinde diyelim, bunu (a) 1on1-minibuffer-frame-top/bottom= nilve (b) değişkenini dinamik olarak uygun konuma bağlama işlevini önererek yapabilirsiniz 1on1-set-minibuffer-frame-top/bottom . Örneğin:

(defadvice 1on1-set-minibuffer-frame-top/bottom (around center activate)
  (let ((1on1-minibuffer-frame-top/bottom  (my-dynamic-position ...)))
    ad-do-it))

( my-dynamic-positionİstediğiniz ölçütleri temel alarak istediğiniz konumu hesaplamak için işlevi tanımlayın (geçerli pencere / çerçeve boyutu ve konumu, ayın evresi, ...).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.