对Emacs-modeline进行裁剪
目录
为了美化mode-line,我做了很多实验.最开始的时候,我用过 smart-mode-line. 然后换成了 powerline. 但是觉得powerline太笨重了,因此换成了 spaceline. 最后我想:"为什么我不直接配置modeline呢,应该不会太难的!"
下面就是我配置的最终结果:
而最终的配置甚至比我的 powerline的配置 还要简洁明了的多.
Show line and column numbers in the mode-line
首先,我想要知道光标所在的列数,这一步很容易实现.
(column-number-mode 1)
Faces
我的“设计”的基色是蓝色:
- buffer name,对我来说是最重要的内容,需要突出显示.
- buffer所在的目录, 比buffer name的重要程度差点, 但是依然很重要,也需要突出显示,只不过不要像buffer name那么突出.
- 使用box来突出显示光标指示的地方太难看了,我把它修改成用蓝色背景色来显示.
- 最后,the inactive mode line 需要与背景融为一体.
(set-face-attribute 'mode-line nil :background "light blue") (set-face-attribute 'mode-line-buffer-id nil :background "blue" :foreground "white") (defface mode-line-directory '((t :background "blue" :foreground "gray")) "Face used for buffer identification parts of the mode line." :group 'mode-line-faces :group 'basic-faces) (set-face-attribute 'mode-line-highlight nil :box nil :background "deep sky blue") (set-face-attribute 'mode-line-inactive nil :inherit 'default)
Simplify the cursor position
我重新定义了一下 mode-line-position
, 让它只显示光标所在的位置. 我根本不需要以百分比的方式来显示位置,也不需要显示像 “Bot”, “Top” , “All” 这样的文本.
当我还是Emacs新手的时候,这些东西时常把我搞迷糊了:-)
我这里保留了 mode-line-position
初始值中各元素的设置,如果需要的话可以取消对这些元素的注释即可.
而且我还为这些以 %
开头的转义字符做了说明.
(setq mode-line-position '(;; %p print percent of buffer above top of window, o Top, Bot or All ;; (-3 "%p") ;; %I print the size of the buffer, with kmG etc ;; (size-indication-mode ("/" (-4 "%I"))) ;; " " ;; %l print the current line number ;; %c print the current column (line-number-mode ("%l" (column-number-mode ":%c")))))
Directory shortening
我希望能在buffer-id前面显示目录信息. 但我不希望显示完整的目录信息,因此需要进行一些精简(下面这个函数并不是我原创的,而是从网上找到的,不过我忘了具体在哪找到的了. 你可以试着在google上搜索一下 “defun shorten-directory”)
(defun shorten-directory (dir max-length) "Show up to `max-length' characters of a directory name `dir'." (let ((path (reverse (split-string (abbreviate-file-name dir) "/"))) (output "")) (when (and path (equal "" (car path))) (setq path (cdr path))) (while (and path (< (length output) (- max-length 4))) (setq output (concat (car path) "/" output)) (setq path (cdr path))) (when path (setq output (concat ".../" output))) output))
Directory name
这里存在的一个问题是,有些buffer,比如 *scratch*
buffer,可能并没有相关联的文件(当然就更不可能有所属目录了), 这时 (buffer-file-name)
的返回值为 nil
.
这种情况下,我就不能去尝试简化目录的显示.
不过不管是否显示目录,我们总是要在最开始的位置上显示一个空格用于将directory/buffer-id与其他的内容隔离开,这样显得好看点.
(defvar mode-line-directory '(:propertize (:eval (if (buffer-file-name) (concat " " (shorten-directory default-directory 20)) " ")) face mode-line-directory) "Formats the current directory.") (put 'mode-line-directory 'risky-local-variable t)
为了对称,我们在buffer-id后也加一个空格:
(setq-default mode-line-buffer-identification (propertized-buffer-identification "%b "))
Binding it together
最后组装出来的 mode-line-format
要比默认的设置更简单一些. 我将一些不需要的显示项都注释掉了.
(setq-default mode-line-format '("%e" mode-line-front-space ;; mode-line-mule-info -- I'm always on utf-8 mode-line-client mode-line-modified ;; mode-line-remote -- no need to indicate this specially ;; mode-line-frame-identification -- this is for text-mode emacs only " " mode-line-directory mode-line-buffer-identification " " mode-line-position ;;(vc-mode vc-mode) -- I use magit, not vc-mode (flycheck-mode flycheck-mode-line) " " mode-line-modes mode-line-misc-info mode-line-end-spaces))