为了美化mode-line,我做了很多实验.最开始的时候,我用过 smart-mode-line. 然后换成了 powerline. 但是觉得powerline太笨重了,因此换成了 spaceline. 最后我想:”为什么我不直接配置modeline呢,应该不会太难的!”
下面就是我配置的最终结果:
而最终的配置甚至比我的 powerline的配置 还要简洁明了的多.
首先,我想要知道光标所在的列数,这一步很容易实现.
(column-number-mode 1)
我的“设计”的基色是蓝色:
- 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)
我重新定义了一下 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")))))
我希望能在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))
这里存在的一个问题是,有些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 "))
最后组装出来的 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))