首页 > mode-line, 中级 > Emacs的状态栏 - mode-line

Emacs的状态栏 - mode-line

2009年11月17日 ahei 发表评论 阅读评论

Emacs中的mode-line是指每个buffer下面的那一行显示buffer相关信息的区域, 相当于一般windows程序中的状态栏, 而它的格式则是由mode-line-format来控制, 这个mode-line-format非常灵活, 可以任意定制.

mode-line-format可以为nil, 字符串, 符号, 列表, cons cell.

  • nil的话很显然就表示啥都不显示, 多出了空间, 但是毕竟buffer中的相关信息都显示不了, 还是不方便.
  • 字符串的话, 和c语言中printf格式类似, %结构含义如下:
    %b — 打印buffer名字
    %f — 打印buffer对应的文件名字
    %F — 打印frame名字
    %* — 根据buffer是否只读, 是否已修改显示%,*,或连字符(-)
    %+ — 根据buffer是否只读, 是否已修改显示*,%,或连字符(-)
    %& — 和%*类似, 不过忽略buffer的只读状态
    %表示buffer只读, *表示buffer已修改, 对于只读buffer, %*打印%, 而%+打印*.
    %s — 打印buffer对应的进程状态
    %l — 打印当前行号
    %c — 打印当前列号, 不过`column-number-mode’必须打开
    %i — 打印当前buffer大小
    %I — 和%i类似, 不过使用k,M,G等单位来显示buffer大小
    %p — 显示当前位置的百分比, 光标在buffer顶端时显示Top, 在低端时显示Bot, 如果一屏能显示完所有buffer中的内容, 则显示All
    %P — 正好与%p相反
    %n — 显示当前buffer是否为Narrow状态
    %t — 当前buffer对应的文件是文本文件还是二进制文件
    %z — 显示输入法, 终端和buffer的编码
    %Z — 与%z类似, 不过还包括显示文件是dos格式还是unix格式
    %e — 当内存占满后, 会显示错误消息
    %@ — 如果当前buffer对应的文件为远程机器上的文件, 则显示@, 否则显示连字符(-)
    $[ -- 对每一次递归编辑, 显示[, $]与此类似
    %% — 显示%
    %- — 显示能足够多的连字符(-)
    与printf中的格式类似, %后面跟的数字限制将要显示的数据的宽度.
  • 符号的话, 根据符号的值分为以下几种情况:
    1. 字符串, 直接把字符串显示在mode-line上, 即使字符串里面含有%结构, 而且这个字符串的文本属性
      将会被忽略, 除非它被标记为`risky-local-variable’.
    2. (eval :FORM), 对FORM进行求值后, 根据求值后的值的类型来进行递归处理, 这里的FORM是任意的elisp代码, 所以能非常灵活的控制mode-line.
    3. `(:propertize ELT PROPS…), 显示指定属性后的字符串, 这样可以以丰富的色彩把字符串显示在mode-line上
    4. 列表的car为符号, 如果这个car不为nil, 则这个列表的cdr被递归处理, 否则这个列表的cddr被递归处理.
    5. 列表的car为字符串或者列表, 那么这个列表的每一个元素被递归处理, 然后再把每一个元素处理后的结果连接起来.
    6. 列表的car为整数, 对列表的cdr进行递归处理, 如果列表的car为正, 则把处理后的结果连在后面, 否则根据长度进行截断.

我上面所说的基本上是翻译mode-line-format的docstring, 英文还可以的同志可以去看docstring, M-x describe-variable mode-line-format.

具备了上面的知识, 我们现在可以对mode-line做一些高级的控制了, 比如在mode-line上用彩色显示当前buffer行数, 这个功能很方便,一眼就能看到当前buffer行数,就像下面这样:

mode-line

mode-line


mode-line

mode-line


mode-line-format的%结构只提供了%p显示当前位置功能,还有%l和%c显示当前行号和列号的功能,就是没有显示当前buffer行数的功能。我配置后的mode-line, 当你选中一块区域后, 会高亮显示这个区域有多少个字符, 没有选中区域的时候, 则显示当前buffer的大小,下面是效果图:
mode line chars

mode line chars


另外用与控制frame标题的frame-title-format的结构与mode-line-format完全相同.

mode-line的配置文件在这里
下面是我的mode-line配置,用彩色显示当前buffer行数的主要是函数`get-lines-4-mode-line’.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
;; -*- Emacs-Lisp -*-
 
;; Time-stamp: <2009-11-22 17:49:25 Sunday by ahei>
 
;; 在mode-line上用彩色显示当前buffer行数
(defun get-lines-4-mode-line ()
  (let ((lines (count-lines (point-min) (point-max))))
    (concat (propertize
             (format "%dL" lines)
             'mouse-face 'mode-line-highlight
             ;; 加上颜色
             'face 'mode-line-lines-face
             'help-echo (format "%d lines" lines)) " ")))
 
(size-indication-mode 1)
(setq-default mode-line-buffer-identification (propertized-buffer-identification "%b"))
 
(if is-after-emacs-23
    (setq-default
     mode-line-position
     `((:eval (get-lines-4-mode-line))
       (1 ,(propertize
            "%p"
            'local-map mode-line-column-line-number-mode-map
            'mouse-face 'mode-line-highlight
            'help-echo "Size indication mode\n\
mouse-1: Display Line and Column Mode Menu"))
       (size-indication-mode
        (" "
         (:eval
          (propertize
           (if (and transient-mark-mode mark-active)
               (format "%d chars" (abs (- (mark t) (point))))
             "%I")
           'face (and transient-mark-mode mark-active 'region)
           '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
          (1 ,(propertize
               " (%l,%c)"
               'local-map mode-line-column-line-number-mode-map
               'mouse-face 'mode-line-highlight
               'help-echo "Line number and Column number\n\
mouse-1: Display Line and Column Mode Menu"))
          (1 ,(propertize
               " L%l"
               'local-map mode-line-column-line-number-mode-map
               'mouse-face 'mode-line-highlight
               'help-echo "Line Number\n\
mouse-1: Display Line and Column Mode Menu"))))
        ((column-number-mode
          (1 ,(propertize
               " C%c"
               'local-map mode-line-column-line-number-mode-map
               'mouse-face 'mode-line-highlight
               'help-echo "Column number\n\
mouse-1: Display Line and Column Mode Menu")))))))
  (let* ((help-echo "mouse-1: select (drag to resize), mouse-2 = C-x 1, mouse-3 = C-x 0"))
    (setq-default
     mode-line-position
     `((:eval (get-lines-4-mode-line))
       (1 ,(propertize "%p" 'help-echo help-echo))
       (size-indication-mode
        (1 ,(propertize " %I" 'help-echo help-echo)))
       (line-number-mode
        ((column-number-mode
          (1 ,(propertize " (%l,%c)" 'help-echo help-echo))
          (1 ,(propertize " L%l" 'help-echo help-echo))))
        ((column-number-mode
          (1 ,(propertize " C%c" 'help-echo help-echo)))))))))
 
(let* ((help-echo
        "mouse-1: Select (drag to resize)\n\
mouse-2: Make current window occupy the whole frame\n\
mouse-3: Remove current window from display")
       (recursive-edit-help-echo "Recursive edit, type C-M-c to get out")
       (standard-mode-line-modes
        (list
         " "
         (propertize "%[" 'help-echo recursive-edit-help-echo)
         (propertize "(" 'help-echo help-echo)
         `(:propertize ("" mode-name)
                       help-echo "Major mode\n\
mouse-1: Display major mode menu\n\
mouse-2: Show help for major mode\n\
mouse-3: Toggle minor modes"
                       mouse-face mode-line-highlight
                       local-map ,mode-line-major-mode-keymap)
         '("" mode-line-process)
         `(:propertize ("" minor-mode-alist)
                       mouse-face mode-line-highlight
                       help-echo "Minor mode\n\
mouse-1: Display minor mode menu\n\
mouse-2: Show help for minor mode\n\
mouse-3: Toggle minor modes"
                       local-map ,mode-line-minor-mode-keymap)
         (propertize "%n" 'help-echo "mouse-2: Remove narrowing from the current buffer"
                     'mouse-face 'mode-line-highlight
                     'local-map (make-mode-line-mouse-map
                                 'mouse-1 #'mode-line-widen))
         (propertize ")" 'help-echo help-echo)
         (propertize "%]" 'help-echo recursive-edit-help-echo))))
  (setq-default mode-line-modes standard-mode-line-modes)
  (setq-default mode-line-format
                `("%e%t"
                  mode-line-mule-info
                  mode-line-client
                  mode-line-modified
                  mode-line-remote
                  " "
                  mode-line-buffer-identification
                  ,(propertize " " 'help-echo help-echo)
                  mode-line-position
                  (vc-mode vc-mode)
                  mode-line-modes
                  (which-func-mode (" " which-func-format))
                  (working-mode-line-message (" " working-mode-line-message))
                  ,(propertize "-%-" 'help-echo help-echo))))
 
(setq mode-line-format-bak mode-line-format)
(setq mode-line t)
(defun toggle-mode-line ()
  "Toggle mode-line."
  (interactive)
  (if mode-line
      (setq-default mode-line-format nil)
    (setq-default mode-line-format mode-line-format-bak))
  (setq mode-line (not mode-line)))
 
;; 在标题栏显示登陆名称和文件名
(setq frame-title-format
      '((:eval
         (let ((login-name (getenv-internal "LOGNAME")))
           (if login-name (concat login-name "@") "")))
        (:eval (system-name))
        ":"
        (:eval (or (buffer-file-name) (buffer-name)))))
分享家:Addthis中国
GD Star Rating
loading...
Emacs的状态栏 - mode-line, 8.0 out of 10 based on 2 ratings 标签:ahei, buffer, DEA, Elisp, Emacs, face, highlight, IDE, keymap, lightbox, lisp, mode, mode-line, screenshot, se, top, windows, 光标, 定制, 截图, 状态栏, 翻译, 行号, 配置, 配置文件, 颜色

相关日志

分类: mode-line, 中级
  1. 2010年2月3日06:33 | #1

    GUuxHH uollypgalnxv, [url=http://nhgyotxghpvo.com/]nhgyotxghpvo[/url], [link=http://eaptqarwqeig.com/]eaptqarwqeig[/link], http://yhikvcxzovju.com/

    [回复]

    ahei 回复:

    我的博客也开始有广告评论拉?下次再有删无赦!

    [回复]

  2. 2010年2月3日06:34 | #2

    写的挺好 我顶

    [回复]

    ahei 回复:

    谢谢支持。

    [回复]

  3. 2010年2月4日06:36 | #3

    还成

    [回复]

    ahei 回复:

    。。。,好吧,也谢谢。 :)

    [回复]

  4. ashini
    2010年4月16日03:54 | #4

    版本必须23吧?

    [回复]

    ahei 回复:

    @ashini, 不需要阿,Emacs一直有mode line阿

    [回复]

  5. yawp
    2010年11月20日12:24 | #5

    mode-line上面那个行列号是什么时候刷新的?没看懂line-number-mode。

    [回复]

    ahei 回复:

    @yawp, 那个是Emacs内部更新的

    [回复]

  6. 匿名
    2011年1月9日11:30 | #6

    生产 mode-line-position 列表,几个判断当前有没有 toggle on line-number-mode column-number-mode 的语法没看懂,能解释下吗?
    我在本地的 emacs23 上语法报错,后来自己改成了
    (if line-number-mode
    (if column-number-mode

    ))
    就行了,我估计你的那个也是对的,但是在我这里语法报错

    [回复]

    cuiaoxiang 回复:

    @,
    我是 1L,主要是那个 (1 ,(propertize …)) 的语法看不懂,语法报错是我自己的问题

    [回复]

    cuiaoxiang 回复:

    @cuiaoxiang,
    我按照你的思路,稍作了一些改动,改成我目前会的语法,因为是给自己用的,所以把 emacs 版本的判断去掉了

    (setq-default mode-line-position
    (list ‘(:eval
    (let ((lines (count-lines (point-min) (point-max))))
    (propertize
    (format “%dL ” lines)
    ‘help-echo (format “Total %d lines” lines))))
    (propertize
    “%p”
    ‘local-map mode-line-column-line-number-mode-map
    ‘mouse-face ‘mode-line-highlight
    ‘help-echo “Size indication mode\nmouse-1: Display Line and Column Mode Menu”)
    (if size-indication-mode
    ‘(:eval
    (propertize
    (if (and transient-mark-mode mark-active)
    (format ” %d chars” (- (region-end) (region-beginning)))
    ” %I”)
    ‘face (and transient-mark-mode mark-active ‘region)
    ‘local-map mode-line-column-line-number-mode-map
    ‘mouse-face ‘mode-line-highlight
    ‘help-echo “Size indication mode\nmouse-1: Display Line and Column Mode Menu”)))
    (if line-number-mode
    (if column-number-mode
    (propertize
    ” (%l,%c)”
    ‘local-map mode-line-column-line-number-mode-map
    ‘mouse-face ‘mode-line-highlight
    ‘help-echo “Line number and Column number\nmouse-1: Display Line and Column Mode Menu”)
    (propertize
    ” L%l”
    ‘local-map mode-line-column-line-number-mode-map
    ‘mouse-face ‘mode-line-highlight
    ‘help-echo “Line Number\nmouse-1: Display Line and Column Mode Menu”))
    (if column-number-mode
    (propertize
    ” C%c”
    ‘local-map mode-line-column-line-number-mode-map
    ‘mouse-face ‘mode-line-highlight
    ‘help-echo “Column number\nmouse-1: Display Line and Column Mode Menu”)))))

    [回复]

    ahei 回复:

    @cuiaoxiang, see info Elisp->backquote

    [回复]

  7. cuiaoxiang
    2011年1月9日12:19 | #7

    这里能上传图片吗?我现在 mode-line 有个奇怪的问题,图片说明更方便些

    [回复]

    ahei 回复:

    @cuiaoxiang, 不能,你可以到水木Emacs版发贴

    [回复]

  8. cmdblock
    2011年5月1日22:07 | #8

    请问你上面emacs中管理buffer的插件是什么名字?

    [回复]

    ahei 回复:

    @cmdblock, select-buffer,我自己写的,呵呵

    [回复]

  9. cmdblock
    2011年5月2日13:01 | #9

    能够给我一份吗?谢谢!
    邮箱wow328@163.com

    [回复]

    ahei 回复:

    @cmdblock, DEA里面有,http://code.google.com/p/dea/

    [回复]

  10. cmdblock
    2011年5月3日00:57 | #10

    @cmdblock
    我下载了,然后在_emacs中做了如下配置,可是还是出了问题,大哥你能写一份这个插件的安装吗?我在网上找了很久,只有你这个buffer管理插件,符合我的要求。
    ;;管理buffer
    (load-file “~/my-lisp/util.el”)
    (load-file “~/my-lisp/ahei-face.el”)
    (load-file “~/my-lisp/diff-mode.el”)
    (load-file “~/my-lisp/select-buffer”)
    (require ’select-buffer)

    启动时,出了下面这个问题:
    Loading d:/emacs/my-lisp/ahei-face.el (source)…
    byte-code: Symbol’s value as variable is void: warning-suppress-types

    [回复]

  1. 本文目前尚无任何 trackbacks 和 pingbacks.
:wink: :-| :-x :twisted: :) 8-O :( :roll: :-P :oops: :-o :mrgreen: :lol: :idea: :-D :evil: :cry: 8) :arrow: :-? :?: :!: