许多商业文字处理器都有默认行为,当文档中的文本行小于可见窗口时,该行为会自动隐藏垂直滚动条;并且,当文档中的文本行大于可见窗口时,滚动条会自动出现。 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
统计每个自动换行的函数。在创建初始帧之后,Emacs似乎设置了initial-frame-default
,因此滚动条在一瞬间可见 - 为了避免看到这一点,修改初始帧的帧参数似乎修复了这个视觉效果问题。现在使用window-text-height
代替window-height
- 返回的高度不包括分隔符,模式行,任何标题行,也不包括文本区域底部的任何部分高度行。< / em>在使用linum-mode
,post-command-hook
和change-major-mode-hook
方面复制了window-configuration-change-hook
使用的方法。添加window-live-p
条件以避免在启动Emacs时出现post-command-hook
错误,同时各种缓冲区加载时看不到。添加处理narrow-to-region
的条件 - 仍然不确定为什么这种情况会导致Emacs在循环中冻结或什么 - 现在需要解决方法。 2014年1月19日的最新版Emacs Trunk似乎解决了以前版本中遇到的视觉显示问题 - 因此,不再需要redraw-frame
。将(redisplay t)
添加到函数count-vertical-lines
,这会在切换缓冲区时加快显示新缓冲区的速度。为缓冲区添加了regexp,它总是有滚动条或从不有滚动条。
编辑(2014年1月20日):只添加了一个主要条件,即有一个实时窗口,并从lawlist-scroll-bar
函数的各个分支中删除了相同的条件。为narrow-to-region
情况添加了附加条件,以便仅在缩小之前存在滚动条时才需要删除滚动条。
编辑(2014年1月21日):通过此修订,不再需要计算行数(导致大缓冲区减慢)。新方法是基于四(4)个点的简单数学计算,这些点仅在几分之一秒内确定 - 即point-min
,point-max
,window-start
和{{ 1}}。如果window-end
移出屏幕,则添加滚动条 - 我认为这种行为是有道理的 - 虽然,我确实停下来思考滚动条是否也应该作为视觉表示是否在无论point-min
是否移出窗口,point-min
到point-max
的参数实际上都可以放入窗口。这个例子中没有一个钩子能够处理point-min
情况(针对同一帧的同一个窗口,两个已经有焦点) - 所以,我创建了自己的display-buffer
(这是超出本例范围)。
display-buffer-hook
支持regexp功能:
;;;;;;;;;;;;;;;;;;;;;;;;;; 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)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
答案 0 :(得分:3)
目前尚不清楚“动态”是什么意思。为什么不举例说明您正在寻找的行为以及您看到的行为?
如果您只想以交互方式,挂钩或代码方式打开/关闭滚动条,那么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-mode
或set-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")))))))))
答案 1 :(得分:2)
如果您习惯只使用滚动条作为您在缓冲区中的位置的可视指示器(而不是查看模式行),您可能会喜欢yascroll之类的包。它使用条纹显示滚动条,如果文档中的文本行小于可见窗口,它就不会显示它。
优点是没有小部件从屏幕上显示真实状态。
缺点是您无法使用鼠标滚动条(有些用户从不这样做,反正)