emacs缓冲区上的垂直填充或边距

时间:2014-07-30 15:20:29

标签: emacs elisp emacs24

似乎有太多的emacs模式用于添加水平填充(请参阅https://github.com/ikame/centered-window-mode),但没有用于垂直填充。

我希望能够指定填充emacs缓冲区顶部和底部的高度。我的动机是在全屏模式下进行截屏和演示,因为投影机可能无法显示该内容,所以处于最顶层或底部可能会有问题。

2 个答案:

答案 0 :(得分:2)

以上是我上述评论中提到的一个概念的示例。此示例在工作窗口下方创建一个窗口和一个窗口 - 顶部/底部窗口具有不可见的inactive模式行,没有右滚动条,cursor-typenil 。可以在名为screencast-function的函数内手动调整alist窗口高度。

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

答案 1 :(得分:1)

第一次草稿(2014年7月30日):此示例在可见窗口的开头和结尾处创建一个不可见的叠加间隔。然而,模式线仍处于最底层。某些使用叠加层的模式可能与此示例不兼容。要查看此示例,请输入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`.") )))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;