Вертикальное заполнение или поле в буфере Emacs
Похоже, что существует множество режимов emacs для добавления горизонтального заполнения (см. https://github.com/ikame/centered-window-mode), но нет для вертикального.
Я хотел бы иметь возможность указать высоту для заполнения верхней и нижней части буфера Emacs. Моя мотивация - для экранных трансляций и презентаций в полноэкранном режиме, где нахождение сверху или снизу может быть проблематичным, поскольку проектор может не отображать этот контент.
3 ответа
Вот пример одной из концепций, упомянутых в моих комментариях выше. Этот пример создает окно выше и окно под рабочим окном - верхнее / нижнее окна имеют невидимое inactive
строки режима, и нет правых полос прокрутки, и cursor-type
является nil
, Высота окна списка может быть скорректирована вручную внутри функции с именем screencast-function
,
(defun lawlist-split-below (buffer alist)
(let ((window (split-window (selected-window) nil 'below)))
(window--display-buffer buffer window
'window alist display-buffer-mark-dedicated)))
(defun lawlist-split-above (buffer alist)
(let ((window (split-window (selected-window) nil 'above)))
(window--display-buffer buffer window
'window alist display-buffer-mark-dedicated)))
(defun screencast-function ()
(interactive)
(toggle-frame-fullscreen)
(set-face-attribute 'default nil
:background "black" :foreground "white" :font "Courier" :height 180)
(set-face-attribute 'mode-line nil
:height 140 :foreground "black" :background "#eab700" :box nil)
(set-face-attribute 'mode-line-inactive nil
:height 140 :foreground "black" :background "black" :box nil)
(lawlist-split-below (get-buffer-create "foo") '((window-height . 2)))
(with-current-buffer (get-buffer "foo")
(setq cursor-type nil))
(set-window-scroll-bars (get-buffer-window "foo") 0 'right nil)
(lawlist-split-above (get-buffer-create "bar") '((window-height . 2)))
(with-current-buffer (get-buffer "bar")
(setq cursor-type nil))
(set-window-scroll-bars (get-buffer-window "bar") 0 'right nil) )
Первый черновик (30 июля 2014 г.). В этом примере создается невидимая накладка наложения в начале и конце видимого окна. Линия мод, однако, остается в самом низу. Некоторые режимы, использующие наложения, могут быть несовместимы с этим примером. Чтобы увидеть этот пример в действии, просто введите M-x screencast-mode
,
(defun screencast-function
(&optional
screencast-old-window-start
screencast-old-window-end
screencast-old-window-end-forced
screencast-new-window-start
screencast-new-window-end)
(save-excursion
(let* (
(window-start
(cond
(screencast-old-window-start
screencast-old-window-start)
(screencast-new-window-start
screencast-new-window-start)
(t (window-start))))
(window-end
(cond
((and
screencast-old-window-end
screencast-old-window-end-forced
(= screencast-old-window-end screencast-old-window-end-forced))
screencast-old-window-end)
((and
screencast-old-window-end
screencast-old-window-end-forced
(> screencast-old-window-end-forced screencast-old-window-end))
screencast-old-window-end-forced)
(screencast-new-window-end
screencast-new-window-end)
(t (window-end (selected-window) t))))
(top-margin 5)
(bottom-margin 5)
end-point
(top-margin-overlay
(propertize (char-to-string ?\uE001)
'display `((space :align-to 0 :height ,top-margin))))
(bottom-margin-overlay
(propertize (char-to-string ?\uE001)
'display `((space :align-to 0 :height ,bottom-margin)))) )
(screencast-delete-overlays (point-min) (point-max))
(setq top-margin-overlay-string top-margin-overlay)
(setq bottom-margin-overlay-string bottom-margin-overlay)
(overlay-put (make-overlay window-start window-start)
'before-string top-margin-overlay)
(setq window-end (window-end nil t))
(goto-char window-end)
(vertical-motion (- 2 bottom-margin))
(setq end-point (point))
(overlay-put (make-overlay end-point end-point)
'before-string bottom-margin-overlay)
(setq screencast-overlays-exist-p t) )))
(defun screencast-remove-overlays (beg end name val)
"Remove the overlays."
;; DEBUGGING
;; (unless (and beg end name val)
;; (message "ERROR -- beg: %s | end: %s | name: %s | val: %s" beg end name val))
(when (and beg end name val)
(overlay-recenter end)
(dolist (o (overlays-in beg end))
(when (eq (overlay-get o name) val)
(delete-overlay o)))))
(defun screencast-delete-overlays (start end)
"Delete overlays from `start` to `end`."
(when screencast-overlays-exist-p
(dolist (ov `(
,top-margin-overlay-string
,bottom-margin-overlay-string ))
(screencast-remove-overlays start end 'before-string ov))
(setq screencast-overlays-exist-p nil)))
(defvar top-margin-overlay-string nil
"This local variable stores the `top-margin-overlay-string`.")
(make-variable-buffer-local 'top-margin-overlay-string)
(defvar bottom-margin-overlay-string nil
"This local variable stores the `bottom-margin-overlay-string`.")
(make-variable-buffer-local 'bottom-margin-overlay-string)
(defvar screencast-overlays-exist-p nil
"A simple test for the existence of screencast overlays.")
(make-variable-buffer-local 'screencast-overlays-exist-p)
(defvar screencast-old-window-start nil
"This local variable is set within the `post-command-hook`; and,
is also used by the `window-scroll-functions` hook.")
(make-variable-buffer-local 'screencast-old-window-start)
(defvar screencast-old-window-end nil
"This local variable is set within the `post-command-hook`; and,
is also used by the `window-scroll-functions` hook.")
(make-variable-buffer-local 'screencast-old-window-end)
(defvar screencast-old-window-end-forced nil
"This local variable is set within the `post-command-hook`; and,
is also used by the `window-scroll-functions` hook.")
(make-variable-buffer-local 'screencast-old-window-end-forced)
(defvar screencast-new-window-start nil
"This local variable is set within the `window-scroll-functions`.")
(make-variable-buffer-local 'screencast-new-window-start)
(defvar screencast-new-window-end nil
"This local variable is set within the `window-scroll-functions`.")
(make-variable-buffer-local 'screencast-new-window-end)
(defun screencast-post-command-hook ()
"NOT good for things like: `beginning-of-buffer`; `end-of-buffer`; `yank`; etc.
NOTE: When using `this-command` in conjunction with the `post-command-hook`,
the `window-scroll-functions` hook would need to use `last-command`."
(when
(and
(not (minibufferp))
(window-live-p (get-buffer-window (current-buffer))))
(setq screencast-old-window-start (window-start))
(setq screencast-old-window-end (window-end))
(setq screencast-old-window-end-forced (window-end nil t))
(when
(or
(and
(not (< (point) screencast-old-window-start))
(not (> (point) screencast-old-window-end))
(not (> (point) screencast-old-window-end-forced)))
;; special situation when deleting region greater than size of window.
(and
(region-active-p)
(< screencast-old-window-end 0))
;; special situation when deleting region greater than size of window.
(and
(region-active-p)
(> (point) screencast-old-window-start)
(> (point) screencast-old-window-end)
(< (point) screencast-old-window-end-forced)) )
(screencast-function screencast-old-window-start screencast-old-window-end screencast-old-window-end-forced nil nil) )))
(defun screencast-window-scroll-functions (win _start)
"Good for things like: `beginning-of-buffer`; `end-of-buffer`; `yank`; etc.
NOTE: When using `this-command` in conjunction with the `post-command-hook`,
the `window-scroll-functions` hook would need to use `last-command`."
(when
(and
screencast-old-window-start
screencast-old-window-end
screencast-old-window-end-forced
(not (minibufferp))
(window-live-p (get-buffer-window (current-buffer))))
(when
(or
(not (= _start screencast-old-window-start))
(< (point) screencast-old-window-start)
(> (point) screencast-old-window-end)
(> (point) screencast-old-window-end-forced))
(setq screencast-new-window-start _start)
(setq screencast-new-window-end (window-end win t))
(screencast-function nil nil nil screencast-new-window-start screencast-new-window-end)
(setq screencast-old-window-start nil)
(setq screencast-old-window-end nil)
(setq screencast-old-window-end-forced nil))))
(define-minor-mode screencast-mode
"A minor-mode for screencasts."
:init-value nil
:lighter " screencast"
:keymap nil
:global nil
:group nil
(cond
(screencast-mode
(condition-case error
(progn
(setq scroll-conservatively 101)
(add-hook 'post-command-hook 'screencast-post-command-hook nil t)
(add-hook 'window-scroll-functions 'screencast-window-scroll-functions nil t)
(message "Turned ON `screencast-mode`."))
(error
(screencast-mode 0)
(signal (car error) (cdr error)))))
((not screencast-mode)
(remove-hook 'post-command-hook 'screencast-post-command-hook t)
(remove-hook 'window-scroll-functions 'screencast-window-scroll-functions t)
(screencast-delete-overlays (point-min) (point-max))
(message "Turned OFF `screencast-mode`.") )))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Я создал второстепенный мод, связанный с этим, который теперь доступен на MELPA:
TopSpace — прокрутка над верхней строкой для вертикального центрирования верхнего текста в Emacs.