gpt4 book ai didi

emacs - 如何根据文本高度的需要自动添加/删除滚动条

转载 作者:行者123 更新时间:2023-12-04 12:21:23 29 4
gpt4 key购买 nike

许多商业文字处理器都有一个默认行为,即当文档中的文本行数少于可见窗口时自动隐藏垂直滚动条;并且,当文档中的文本行大于可见窗口时,滚动条会自动出现。 Emacs 缺少这种能力,我希望它成为各种不同模式下的默认行为。

有没有人有一些想法如何随着文档的大小(文本行)增加或减少而自动删除或添加滚动条?

我正在考虑使用@phils 在相关线程中的先前示例将其编织到行号的函数中:https://stackoverflow.com/a/10593165/2112489

我希望即使我不使用它也能工作 linum-mode .但是,我不认为滚动条功能应该在每个命令之后运行——它应该只在添加或减去新行时运行,考虑到 visual-line-mode (即,包装处于事件状态)可能处于事件状态。

以下片段的灵感来自@abo-abo 在相关线程中的先前回答:https://stackoverflow.com/a/20923695/2112489

(cond
((not (> (count-lines (point-min) (point-max)) (window-height)))
(set-window-scroll-bars (get-buffer-window (buffer-name) (selected-frame)) 0 nil))
((and
(> (count-lines (point-min) (point-max)) (window-height))
(not (equal (window-scroll-bars) `(15 2 t nil))))
(set-window-scroll-bars (get-buffer-window (buffer-name) (selected-frame)) 15 'right)))

编辑 (2014 年 1 月 17 日):工作草案基于 @Drew 对此线程的有用回答。

编辑 (2014 年 1 月 19 日):添加了一个函数来使用 vertical-motion 计算每个换行的行.设置 initial-frame-default似乎在创建初始帧后由 Emacs 读取,因此滚动条在一瞬间是可见的——为了避免看到这一点,修改初始帧的帧参数似乎可以解决这个视觉问题。正在使用 window-text-height而不是 window-height -- 返回的高度不包括分隔线、模式行、任何标题行,也不包括文本区域底部的任何部分高度行。复制 linum-mode使用的方法在使用方面—— post-command-hook , change-major-mode-hook ,以及 window-configuration-change-hook )。已添加 window-live-p避免条件 post-command-hook启动 Emacs 时出现错误,而各种缓冲区正在加载看不见。添加条件处理 narrow-to-region -- 仍然不确定为什么这种情况会导致 Emacs 在循环中卡住或其他原因 -- 现在需要解决方法。 2014 年 1 月 19 日发布的最新版本的 Emacs Trunk 似乎修复了先前版本中遇到的视觉显示问题——因此, redraw-frame不再需要。已添加 (redisplay t)到函数 count-vertical-lines ,这会在切换缓冲区时加快显示新缓冲区的速度。为始终具有滚动条或从不具有滚动条的缓冲区添加了正则表达式。

编辑 (2014 年 1 月 20 日):仅添加了一个存在实时窗口的主要条件,并从 lawlist-scroll-bar 的各个分支中删除了相同的条件。功能。为 narrow-to-region 添加了附加条件仅当在缩小之前存在滚动条时才需要移除滚动条。

编辑 (2014 年 1 月 21 日):在此修订版中,不再需要计算行数(这会导致大型缓冲区变慢)。新方法是基于四 (4) 个点的简单得多的数学计算,这些点在几分之一秒内确定 - 即 point-min , point-max , window-startwindow-end .如 point-min移出屏幕,添加滚动条——我认为这种行为是有道理的——虽然,我确实停下来思考滚动条是否也应该作为 point-min 参数内的字符的可视化表示至 point-max不管 point-min 是否真的可以放入窗口已经移到窗外。此示例中的所有钩子(Hook)都无法处理 display-buffer情况(针对同一个框架的同一个窗口,两者都已经有焦点)——所以,我创建了自己的 display-buffer-hook (这超出了本示例的范围)。
;;;;;;;;;;;;;;;;;;;;;;;;;; LAWLIST SCROLL BAR MODE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defvar regexp-always-scroll-bar '("\\.yes" "\\*Scroll-Bar\\*")
"Regexp matching buffer names that will always have scroll bars.")

(defvar regexp-never-scroll-bar '("\\.off" "\\.not")
"Regexp matching buffer names that will never have scroll bars.")

(add-to-list 'default-frame-alist '(vertical-scroll-bars . nil))

(modify-all-frames-parameters (list (cons 'vertical-scroll-bars nil)))

(defun lawlist-scroll-bar ()
(when (window-live-p (get-buffer-window (current-buffer)))
(redisplay t)
(cond
;; not regexp matches | not narrow-to-region
((and
(not (regexp-match-p regexp-always-scroll-bar (buffer-name)))
(not (regexp-match-p regexp-never-scroll-bar (buffer-name)))
(equal (- (point-max) (point-min)) (buffer-size)))
(cond
;; Lines of text are less-than or equal-to window height,
;; and scroll bars are present (which need to be removed).
((and
(<= (- (point-max) (point-min)) (- (window-end) (window-start)))
(equal (window-scroll-bars) `(15 2 right nil)))
(set-window-scroll-bars (selected-window) 0 'right nil))
;; Lines of text are greater-than window height, and
;; scroll bars are not present and need to be added.
((and
(> (- (point-max) (point-min)) (- (window-end) (window-start)))
(not (equal (window-scroll-bars) `(15 2 right nil))))
(set-window-scroll-bars (selected-window) 15 'right nil))))
;; Narrow-to-region is active, and scroll bars are present
;; (which need to be removed).
((and
(not (equal (- (point-max) (point-min)) (buffer-size)))
(equal (window-scroll-bars) `(15 2 right nil)))
(set-window-scroll-bars (selected-window) 0 'right nil))
;; not narrow-to-region | regexp always scroll-bars
((and
(equal (- (point-max) (point-min)) (buffer-size))
(regexp-match-p regexp-always-scroll-bar (buffer-name)))
(set-window-scroll-bars (selected-window) 15 'right nil))
;; not narrow-to-region | regexp never scroll-bars
((and
(equal (- (point-max) (point-min)) (buffer-size))
(regexp-match-p regexp-never-scroll-bar (buffer-name)))
(set-window-scroll-bars (selected-window) 0 'right nil)))))

(define-minor-mode lawlist-scroll-bar-mode
"This is a custom scroll bar mode."
:lighter " sc"
(if lawlist-scroll-bar-mode
(progn
(add-hook 'post-command-hook 'lawlist-scroll-bar nil t)
;; (add-hook 'change-major-mode-hook 'lawlist-scroll-bar nil t)
;; (add-hook 'window-configuration-change-hook 'lawlist-scroll-bar nil t)
)
(remove-hook 'post-command-hook 'lawlist-scroll-bar t)
(remove-hook 'change-major-mode-hook 'lawlist-scroll-bar t)
(remove-hook 'window-configuration-change-hook 'lawlist-scroll-bar t)))

(define-globalized-minor-mode global-lawlist-scroll-bar-mode
lawlist-scroll-bar-mode lawlist-scroll-bar-on)

(defun lawlist-scroll-bar-on ()
(unless (minibufferp)
(lawlist-scroll-bar-mode 1)))

(global-lawlist-scroll-bar-mode)

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

支持正则表达式功能:
;; https://github.com/kentaro/auto-save-buffers-enhanced
;; `regexp-match-p` function modified by @sds on stackoverflow
;; https://stackoverflow.com/questions/20343048/distinguishing-files-with-extensions-from-hidden-files-and-no-extensions
(defun regexp-match-p (regexps string)
(and string
(catch 'matched
(let ((inhibit-changing-match-data t)) ; small optimization
(dolist (regexp regexps)
(when (string-match regexp string)
(throw 'matched t)))))))

最佳答案

目前尚不清楚您所说的“即时”是什么意思。为什么不举一个你正在寻找的行为和你看到的行为的例子呢?

如果您只想以交互方式、 Hook 或代码打开/关闭滚动条,那么 scroll-bar-mode应该是你所需要的。但我只是疯狂地猜测你真正在寻找什么。

您也可以使用 menu-bar-no-scroll-bar , menu-bar-left-scroll-bar , 和 menu-bar-right-scroll-bar .或者只是执行每个命令的作用:(customize-set-variable 'scroll-bar-mode WHATEVER) .或使用 set-scroll-bar-modeset-window-scroll-bars , 相似地。这取决于您要寻找的行为。

我推荐 M-x apropos scroll-bar . (或者,如果您使用 Icicles ,只需 C-h f scroll-bar S-TAB ,然后重复 C-M-down ...)

更新 (在您的评论回复之后)

您可以将其添加到 mode-line-position ,以便模式行的更新自动触发打开/关闭滚动条。这几乎有效,例如:

(setq-default
mode-line-position
'(:eval
(progn
(if (> (count-lines (point-min) (point-max)) (window-height))
(set-window-scroll-bars nil 20 t)
(set-window-scroll-bars nil 0 t))
`((-3 ,(propertize
"%p"
'local-map mode-line-column-line-number-mode-map
'mouse-face 'mode-line-highlight
'help-echo "Buffer position, mouse-1: Line/col menu"))
(line-number-mode
((column-number-mode
(10 ,(propertize
" (%l,%c)"
'face (and (> (current-column)
modelinepos-column-limit)
'modelinepos-column-warning)
'local-map mode-line-column-line-number-mode-map
'mouse-face 'mode-line-highlight
'help-echo "Line and column, mouse-1: Line/col menu"))
(6 ,(propertize
" L%l"
'local-map mode-line-column-line-number-mode-map
'mouse-face 'mode-line-highlight
'help-echo "Line number, mouse-1: Line/col menu"))))
((column-number-mode
(5 ,(propertize
" C%c"
'face (and (> (current-column)
modelinepos-column-limit)
'modelinepos-column-warning)
'local-map mode-line-column-line-number-mode-map
'mouse-face 'mode-line-highlight
'help-echo "Column number, mouse-1: Line/col menu")))))))))

您也可以使用以下内容,它使用 Stefan 的 suggestion
为了让它更好地处理缩放文本, visual-line-mode 、图像等。但是,在这种情况下,只要某些文本由于滚动而位于窗口之外,无论该文本是否适合窗口,滚动条都会启动。这是否是一项功能由您决定。 ;-)
(setq-default
mode-line-position
'(:eval
(let ((scroll-bars (nth 2 (window-scroll-bars))))
(if (or (> (point-max) (window-end)) (< (point-min) (window-start)))
(unless scroll-bars (set-window-scroll-bars nil 20 t))
(when scroll-bars (set-window-scroll-bars nil 0 t)))
(unless (equal scroll-bars (nth 2 (window-scroll-bars))) (redraw-frame))
`((-3 ,(propertize
"%p"
'local-map mode-line-column-line-number-mode-map
'mouse-face 'mode-line-highlight
'help-echo "Buffer position, mouse-1: Line/col menu"))
(line-number-mode
((column-number-mode
(10 ,(propertize
" (%l,%c)"
'face (and (> (current-column)
modelinepos-column-limit)
'modelinepos-column-warning)
'local-map mode-line-column-line-number-mode-map
'mouse-face 'mode-line-highlight
'help-echo "Line and column, mouse-1: Line/col menu"))
(6 ,(propertize
" L%l"
'local-map mode-line-column-line-number-mode-map
'mouse-face 'mode-line-highlight
'help-echo "Line number, mouse-1: Line/col menu"))))
((column-number-mode
(5 ,(propertize
" C%c"
'face (and (> (current-column)
modelinepos-column-limit)
'modelinepos-column-warning)
'local-map mode-line-column-line-number-mode-map
'mouse-face 'mode-line-highlight
'help-echo "Column number, mouse-1: Line/col menu")))))))))

关于emacs - 如何根据文本高度的需要自动添加/删除滚动条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21175099/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com