Làm cách nào để hiển thị nội dung của xe buýt nhỏ ở giữa khung emacs?


20

Khi làm việc trên khung Emacs được tối đa hóa, có nội dung của màn hình hiển thị vùng thu nhỏ / tiếng vang ở phía dưới màn hình có thể khó nhìn thấy, nhưng cũng gây mất tập trung vào văn bản được chỉnh sửa khi gõ lệnh - khá là vấn đề về khả năng sử dụng.

Có cách nào để di chuyển vùng thu âm / tiếng vang ở trung tâm của bộ đệm emacs hiện tại không, trên văn bản đang được chỉnh sửa khi xe buýt nhỏ đang hoạt động, hoặc, tốt hơn, để nắm bắt nội dung của xe buýt nhỏ và hiển thị nó ở giữa của bộ đệm hiện tại trong khi gõ lệnh?


Để đầy đủ, tôi nên thêm rằng giải pháp hiện tại của tôi cho vấn đề về khả năng sử dụng này là tăng kích thước phông chữ của bộ thu nhỏ, nhưng nó trông có vẻ ngớ ngẩn trên các khung không được tối đa hóa.
Sébastien Le Callonnec

Câu trả lời:


10

Popup Minibuffer tại Trung tâm

Đây là một cách để làm chính xác những gì bạn yêu cầu: hiển thị bộ thu nhỏ ở giữa màn hình .

  1. Có khung riêng cho xe buýt nhỏ
  2. Đặt nó ở trung tâm
  3. Nâng khung hình này bất cứ khi nào xe buýt nhỏ đạt được trọng tâm.

Điều đó tương đối dễ dàng để đạt được và là những gì bạn sẽ nhận được với oneonone.elgói (như @Drew chỉ ra). Vấn đề với cách tiếp cận này, đó là xe buýt nhỏ cũng được sử dụng cho các tin nhắn, vì vậy việc giấu nó không phải là điều gì đó rất thuận tiện. Đừng lo lắng! Tôi đã đưa ra một giải pháp khác.

  1. Có một xe buýt nhỏ thứ hai được hiển thị trên một khung riêng biệt.
  2. Đặt nó ở trung tâm.
  3. Sử dụng khung thứ hai cho các lệnh tương tác, trong khi bộ thu nhỏ ban đầu (thứ nhất) được sử dụng để lặp lại tin nhắn.

Thực hiện

Để thực hiện điều này, chúng ta cần tạo khung mini cho bộ khởi động emacs.

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

Sau đó, chúng tôi vá read-from-minibufferđể sử dụng bộ thu nhỏ thứ hai này, thay vì bộ thu nhỏ của khung ban đầu.

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

Điều này có thể không làm việc với tất cả mọi thứ hoàn toàn, nhưng nó làm việc trên tất cả mọi thứ tôi đã cố gắng cho đến nay --- find-file, ido-switch-buffer, eval-expression. Nếu bạn làm tìm thấy bất kỳ trường hợp ngoại lệ, bạn có thể vá các chức năng trên cơ sở từng trường hợp cụ thể bằng cách gọi use-popup-minibuffervào chúng.

Vị trí gần điểm

Để định vị khung hình xe buýt nhỏ này gần độ cao của điểm, chỉ cần xác định một cái gì đó giống như chức năng sau đây. Nó không hoàn hảo (trên thực tế, rất tệ trong nhiều trường hợp), nhưng nó làm rất tốt việc ước tính chiều cao điểm.

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

Thay vì loay hoay với (setf (symbol-function function) ...)bạn, bạn nên sử dụng advice-add(hoặc cũ hơn ad-add-advice).
Stefan

6

Minibuffer ở đầu

Hiển thị bộ thu nhỏ ở giữa màn hình rất phức tạp. Một lựa chọn hợp lý (mà bạn có thể hoặc không thể tìm thấy dễ đọc hơn) là di chuyển nó lên đầu.

Bạn có thể định cấu hình vị trí (hoặc sự tồn tại) của xe buýt nhỏ của khung với minibuffertham số khung trong initial-frame-alist biến.

Khung riêng

Đặt tham số nilsẽ cấu hình khung để không có bộ thu nhỏ và Emacs sẽ tự động tạo một khung bộ thu nhỏ riêng cho bạn. Bạn có thể định vị hai khung này bằng trình quản lý cửa sổ của HĐH hoặc bạn có thể thực hiện nó từ Emacs.

Đoạn mã sau kiểm tra cách đặt khung xe buýt nhỏ ở trên cùng, với khung thông thường ngay bên dưới khung, nhưng bạn chắc chắn sẽ phải thay đổi số để tính kích thước màn hình của mình.

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

Cách nhanh nhất để điều chỉnh điều này là thay đổi kích thước các khung trong trình quản lý cửa sổ của bạn và sau đó đánh giá (frame-parameters)để xem các giá trị tham số bạn có.

Cùng khung

Một khả năng khác là đặt minibuffertham số cho một cửa sổ. Thật không may, tôi không thể làm cho nó hoạt động cho một cửa sổ trong cùng một khung.


5

Thư viện oneonone.elcung cấp cho bạn điều này ra khỏi hộp.

Chỉ cần tùy chỉnh tùy chọn 1on1-minibuffer-frame-top/bottomđến vị trí bạn muốn cho khung xe buýt nhỏ độc lập. Giá trị là số pixel từ trên cùng (nếu không âm) hoặc dưới cùng (nếu âm) của màn hình của bạn. Ví dụ: đặt giá trị cho chiều cao hiển thị của bạn chia cho 2, để căn giữa nó theo chiều dọc.

Thay vào đó, nếu bạn muốn nó được định vị linh hoạt, hãy nói ở trung tâm dọc của khung hiện tại, sau đó bạn có thể thực hiện điều đó bằng cách (a) rời 1on1-minibuffer-frame-top/bottom= nilvà (b) chức năng tư vấn 1on1-set-minibuffer-frame-top/bottom để liên kết biến đó với vị trí thích hợp. Ví dụ:

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

(Xác định hàm my-dynamic-positionđể tính toán vị trí bạn muốn, dựa trên bất kỳ tiêu chí nào bạn muốn (kích thước & vị trí cửa sổ / khung hình hiện tại, pha của mặt trăng, ...).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.