首页 > Elisp, mode-line, 中级, 好玩的 > 在mode-line上标记svn状态

在mode-line上标记svn状态

2010年1月28日 ahei 发表评论 阅读评论

psvn.el是一款Emacs下的svn插件,前段时间把Emacs升级到23,升级整理的过程中,看到psvn.el,遂去它的主页把它的最新版本down下来,试了一下,果然功能又强大多了,一个我一直想要的功能就是在mode-line上显示当前文件的svn状态,比如是否修改过,就像下面这样:

svn文件,未修改


svn文件,已修改


svn文件,刚增加


psvn用一个带有颜色的圆表示文件的状态,绿色的圆表示未修改过,淡红色的圆表示已经修改过。

由于psvn包只有一个文件psvn.el,所以它那个圆应该不是事先做好的图片,应该是程序里面生成的。那这个就比较有意思了,竟然可以在Emacs中画圆,赶快去瞧瞧它是杂实现的。

由于这个圆是在mode-line上画的,直接去psvn.el里面去搜索mode-line,搜到一个mode-line-process,还有一个:

(setq svn-status-mode-line-process-status (format " running %s" cmdtype))

平时运行svn-status命令的时候,会看到状态栏显示running,看来是控制这个mode-line-process来实现的,看一下mode-line-process的文档:

1
2
3
4
5
6
7
8
mode-line-process is a variable defined in `bindings.el'.
Its value is nil
 
  Automatically becomes buffer-local when set in any fashion.
 
Documentation:
Mode-line control for displaying info on process status.
Normally nil in most modes, since there is no process to display.

看来真是它,我们来试试:

(setq mode-line-process " hi, I'm mode-line-process")

C-x C-e执行上面的语句,mode-line变成:

mode-line-process


果然!

继续搜索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
(defun svn-status-state-mark-modeline-dot (color)
  (propertize "    "
              'help-echo 'svn-status-state-mark-tooltip
              'display
              `(image :type xpm
                      :data ,(format "/* XPM */
static char * data[] = {
\"18 13 3 1\",
\"  c None\",
\"+ c #000000\",
\". c %s\",
\"                  \",
\"       +++++      \",
\"      +.....+     \",
\"     +.......+    \",
\"    +.........+   \",
\"    +.........+   \",
\"    +.........+   \",
\"    +.........+   \",
\"    +.........+   \",
\"     +.......+    \",
\"      +.....+     \",
\"       +++++      \",
\"                  \"};"
                                     color)
                      :ascent center)))

看这函数名,代码和图形,有点像是它画的圆,那么我们再来看看这个svn-status-state-mark-modeline-dot函数都哪里调用了。继续查找,只有一个地方调用了:

1
2
3
4
5
(defun svn-status-install-state-mark-modeline (color)
  (push `(svn-status-state-mark-modeline
          ,(svn-status-state-mark-modeline-dot color))
        mode-line-format)
  (force-mode-line-update t))

而svn-status-install-state-mark-modeline是svn-status-update-state-mark调用的,svn-status-update-modeline又调用了svn-status-update-state-mark,看来没错了,应该就是svn-status-state-mark-modeline-dot画的圆,为了更加确定一点,来做个实验。

改下svn-status-state-mark-modeline-dot的函数变成这样:

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
(defun generate-circle (tip space edge inside)
  "Generate a circle."
  (propertize " "
              'help-echo tip
              'display
              `(image :type xpm
                      :data ,(format "/* XPM */
static char * data[] = {
\"18 13 3 1\",
\"  c %s\",
\"+ c %s\",
\". c %s\",
\"                  \",
\"       +++++      \",
\"      +.....+     \",
\"     +.......+    \",
\"    +.........+   \",
\"    +.........+   \",
\"    +.........+   \",
\"    +.........+   \",
\"    +.........+   \",
\"     +.......+    \",
\"      +.....+     \",
\"       +++++      \",
\"                  \"
};"
                                     space edge inside)
                      :ascent center)))

然后执行下面的代码:

(insert (generate-circle "我是圆" "None" "black" "red"))

出现下面的截图:

emacs中画圆

(insert (generate-circle "我是月环食" "None" "yellow" "red"))

emacs中画月环食


再来一张膏药旗

(insert (generate-circle "我是膏药旗" "white" "yellow" "red"))

Emacs中画膏药旗


再画个立方体:

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
(defun generate-cube (tip)
  "Generate a cube."
  (propertize " "
              'help-echo tip
              'display
              `(image :type xpm
                      :data ,(format "/* XPM */
static char * data[] = {
\"32 39 5 1\",
\".      c none\",
\"+      c black\",
\"@      c #3070E0\",
\"#      c #F05050\",
\"$      c #35E035\",
\"................+...............\",
\"..............+++++.............\",
\"............+++++@@++...........\",
\"..........+++++@@@@@@++.........\",
\"........++++@@@@@@@@@@++........\",
\"......++++@@++++++++@@@++.......\",
\".....+++@@@+++++++++++@@@++.....\",
\"...+++@@@@+++@@@@@@++++@@@@+....\",
\"..+++@@@@+++@@@@@@@@+++@@@@@++..\",
\".++@@@@@@+++@@@@@@@@@@@@@@@@@@++\",
\".+#+@@@@@@++@@@@+++@@@@@@@@@@@@+\",
\".+##++@@@@+++@@@+++++@@@@@@@@$@.\",
\".+###++@@@@+++@@@+++@@@@@++$$$@.\",
\".+####+++@@@+++++++@@@@@+@$$$$@.\",
\".+#####+++@@@@+++@@@@++@$$$$$$+.\",
\".+######++++@@@@@@@++@$$$$$$$$+.\",
\".+#######+##+@@@@+++$$$$$$@@$$+.\",
\".+###+++##+##+@@++@$$$$$$++$$$+.\",
\".+###++++##+##+@@$$$$$$$@+@$$@+.\",
\".+###++++++#+++@$$@+@$$@++$$$@+.\",
\".+####+++++++#++$$@+@$$++$$$$+..\",
\".++####++++++#++$$@+@$++@$$$$+..\",
\".+#####+++++##++$$++@+++$$$$$+..\",
\".++####+++##+#++$$+++++@$$$$$+..\",
\".++####+++####++$$++++++@$$$@+..\",
\".+#####++#####++$$+++@++++@$@+..\",
\".+#####++#####++$$++@$$@+++$@@..\",
\".++####++#####++$$++$$$$$+@$@++.\",
\".++####++#####++$$++$$$$$$$$+++.\",
\".+++####+#####++$$++$$$$$$$@+++.\",
\"..+++#########+@$$+@$$$$$$+++...\",
\"...+++########+@$$$$$$$$@+++....\",
\".....+++######+@$$$$$$$+++......\",
\"......+++#####+@$$$$$@++........\",
\".......+++####+@$$$$+++.........\",
\".........++###+$$$@++...........\",
\"..........++##+$@+++............\",
\"...........+++++++..............\",
\".............++++...............\"
};"
                                     )
                      :ascent center)))
(insert (generate-cube "我是立方体"))

Emacs中画立方体


再来一张更眩的:

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
(defun generate-compact-disk (tip)
  "Generate one compact disk."
  (propertize " "
              'help-echo tip
              'display
              `(image :type xpm
                      :data ,(format "/* XPM */
static char * data[] = {
\"16 16 8 1\",
\"    c None s None\",
\".   c #808080\",
\"X   c #FFFF00\",
\"o   c #c0c0c0\",
\"O   c black\",
\"+   c #00FFFF\",
\"@   c #00FF00\",
\"#   c white\",
\"     .....      \",
\"   ..XXoooOO    \",
\"  .+XXXoooooO   \",
\" .@++XXoooo#oO  \",
\" .@@+XXooo#ooO  \",
\".oo@@+Xoo#ooooO \",
\".ooo@+.O.oooooO \",
\".oooo@O#OoooooO \",
\".oooo#.O.+ooooO \",
\".ooo#oo#@X+oooO \",
\" .o#oooo@X++oO  \",
\" .#ooooo@XX++O  \",
\"  .ooooo@@XXO   \",
\"   ..ooo@@OO    \",
\"     ..OOO      \",
\"                \"
};"
                                     )
                      :ascent center)))
(insert (generate-compact-disk "我是光盘"))

Emacs中画光盘


其实, 只要你明白xpm的格式, 自己完全可以构建那个data, 画出各种各样的图形.

现在还有个问题,怎么定制这些圆的颜色呢?

我们来看看svn-status-update-mode-line的代码:

1
2
3
4
5
6
(defun svn-status-update-modeline ()
  "Update modeline state dot mark properly"
  (when (and buffer-file-name (svn-status-in-vc-mode?))
    (svn-status-update-state-mark
     (svn-status-interprete-state-mode-color
      (vc-svn-state buffer-file-name)))))

svn-status-update-mode-line把

1
2
(svn-status-interprete-state-mode-color
      (vc-svn-state buffer-file-name))

作为参数传给svn-status-update-state-mark,而svn-status-update-state-mark代码:

1
2
3
(defun svn-status-update-state-mark (color)
  (svn-status-uninstall-state-mark-modeline)
  (svn-status-install-state-mark-modeline color))

svn-status-update-state-mark的参数为颜色,这就是说svn-status-interprete-state-mode-color的作用应该是得到颜色,且来看看它的定义:

1
2
3
4
5
6
7
8
9
10
11
(defsubst svn-status-interprete-state-mode-color (stat)
  "Interpret vc-svn-state symbol to mode line color"
  (case stat
    ('edited "tomato"      )
    ('up-to-date "GreenYellow" )
    ;; what is missing here??
    ;; ('unknown  "gray"        )
    ;; ('added    "blue"        )
    ;; ('deleted  "red"         )
    ;; ('unmerged "purple"      )
    (t "red")))

这个函数的参数是当前文件的svn状态,返回一个颜色字符串。
看来只要改这个函数就能定制颜色了。
等等,难道要直接修改psvn.el吗?当然不需要,而且那是个不好的习惯。由于Elisp不像c等编译型语言,它是解释型语言(也可以编译成字节码),如果你多处定义了同一个函数,后面的会覆盖的前面的定义。根据这个特性,我们就可以在我们自己的配置文件中重新定义一下svn-status-interprete-state-mode-color就可以了,重新定义如下:

1
2
3
4
5
6
7
8
9
10
(defsubst svn-status-interprete-state-mode-color (stat)
  "Interpret vc-svn-state symbol to mode line color"
  (case stat
    ('up-to-date "GreenYellow")
    ('edited     "tomato")
    ('unknown    "gray")
    ('added      "blue")
    ('deleted    "red")
    ('unmerged   "purple")
    (t           "black")))

这样,未修改的文件绿色圆,修改过的淡红色圆,增加的文件蓝色圆,删除的文件红色圆。

分享家:Addthis中国
GD Star Rating
loading...
在mode-line上标记svn状态, 7.0 out of 10 based on 4 ratings 标签:buffer, control, Elisp, Emacs, IDE, irc, lightbox, lisp, mode, mode-line, screenshot, svn-status, 定制, 截图, 插件, 状态栏, 编译, 配置, 配置文件, 配色, 配色, 颜色

相关日志

  1. 2010年1月28日10:46 | #1

    有意思,竟然还能这样。不过你的立方体和光盘图标是怎么画的啊?
    ASCII art?

    [回复]

    ahei 回复:

    不是ascii art,是直接画出图像的。其实你只要懂xpm格式,完全可以自己写那个data, 画各种各样的图像

    [回复]

  2. 2010年1月28日12:02 | #2

    不要这么nb好不好,看到那个立方体震惊了~~
    欢迎来 irc.oftc.net #emacs-cn ,呵呵,里面的 xwl 不知道你知道不

    [回复]

    ahei 回复:

    irc.oftc.net我这打不开,我翻墙过去看,也没看到啥啊

    [回复]

    x 回复:

    @ahei, 看样子没玩过IRC?

    [回复]

    ahei 回复:

    没玩过,但是知道,emacs下还有它的插件

    [回复]

    ahei 回复:

    @ahei, 出糗了, :) 我去irc.oftc.net瞧了,那个xwl我知道的,用过他的dired-isearch。

    [回复]

  3. 2010年2月4日16:18 | #3

    搜索semantic时找到了这个博客,写得很好啊,看来我对Emacs还没有入门呢。曾经试用了我所能找到的所有代码编辑器,还是Emacs配置之后用起来最舒服。我原本想写一篇博文向初学者介绍Emacs,现在看来不用重复造车轮了。

    [回复]

    ahei 回复:

    @Ariesbear, 呵呵,谢谢支持。可以再谢谢阿,每个人都有不同的看法,正如你所说,think different,而且也能对Emacs认识的更清楚一些。

    [回复]

  4. happybabe
    2010年2月10日12:00 | #4

    这么好的域名,可不可以用于建个Emacs的中文讨论区?用fluxbb或phpbb论坛程序很方便啊?

    [回复]

    ahei 回复:

    我之前也有这个打算,不过emacs不像其他东西,用的人少,而且需要花时间,光靠我一个人是不够的,你看水木emacs版都不活跃。

    [回复]

    happybabe 回复:

    @ahei, 有多少人能看得懂水木区的排版?orz…emacser都在哪里热闹呢?

    [回复]

    ahei 回复:

    @happybabe, 还好吧,现在国内emacser应该主要还是在水木emacs版活动。

    [回复]

  5. 2010年8月20日10:49 | #5

    psvn 貌似在 windows下不能用,在windows下 启用 psvn 后 ,输入 svn-state ,指向的是有.svn 的目录, 但是却提示我 Searching for program: no such file or directory, svn

    [回复]

    ahei 回复:

    @kun, 你要装svn命令

    [回复]

    kun 回复:

    @ahei, 我今天试了一下,装了SVN命令,也设置了环境变量,
    输入svn-state 还是提示 Searching for program: no such file or directory, svn. 晕啊

    [回复]

    ahei 回复:

    @kun, 首先你在cmd里面敲SVN有问题吗?其次,你装了之后重启过Emacs吗?

    [回复]

    kun 回复:

    @ahei, 在cmd里 输入svn 命令都没问题,
    emacs也重启过了, svn-admin-create 是 可以用的,svn-status 和 svn-status-update这些都操作不了

    [回复]

    ahei 回复:

    @kun, 那我就不知道了,…

    [回复]

  6. victor
    2010年12月6日19:36 | #6

    Hi, 我在emacs中启用了该扩展以后,当我修改了一个文件以后mode-line上面的颜色是改变了,可是当我提交了以后mode-line上面的颜色却没有自动变回原来的颜色..你们遇到国这种现象吗?

    [回复]

    ahei 回复:

    @victor, M-x revert-buffer

    [回复]

    victor 回复:

    @ahei, 有没有什么办法让我提交了以后自动更新!

    [回复]

    ahei 回复:

    @victor, 那只能自己写个命令提交完调用revert-buffer

    [回复]

    victor 回复:

    @ahei, :-? ..我对lisp不熟,不知道怎么加,可否写个例子阿?

    [回复]

    ahei 回复:

    @victor, 呵呵,所以要学, 学Emacs最重要的就是学这个了, lisp学会了,就无敌了,啥需求都自己搞定, 呵呵

    [回复]

  7. 2011年2月26日10:50 | #7

    ahei大哥,帮我写个显示CUA状态的mode line嘛,只需要像emaci那样有颜色就行了。

    [回复]

    ahei 回复:

    @lynn, 这是我为view-mode写的,你照着写吧:

    (defvar view-mode-line-format
        (propertize "View"
                    'local-map mode-line-minor-mode-keymap
                    'help-echo "mouse-3: minor mode menu"
                    'face 'view-mode-mode-line-face)
        "*Mode line format of `view-mode'.")
     
     
      (put 'view-mode-line-format 'risky-local-variable t)
     
      (setq minor-mode-alist
            (append
             `((view-mode " ") (view-mode ,view-mode-line-format))
             (delq (assq 'view-mode minor-mode-alist) minor-mode-alist) ))

    [回复]

    lynn 回复:

    @ahei, 之前也参照过,但是不知道哪些是重点,现在写好啦:

    (global-set-key (kbd "") 'cua-mode)
    (defun my-cua-mode-setting ()
      (defvar my-cua-mode-have-seted nil)
      (unless my-cua-mode-have-seted
        (setq my-cua-mode-have-seted t)
        (defface cua-mode-mode-line-face
          '((((type tty pc)) :bold t :foreground "blue" :background "white")
    	(t (:background "blue" :foreground "white")))
          "Face used highlight `cua-mode-line-format'.")
        (defvar cua-mode-line-format
          (propertize "CUA"
    		  'local-map mode-line-minor-mode-keymap
    		  'help-echo "mouse-3: minor mode menu"
    		  'face 'cua-mode-mode-line-face)
          "*Mode line format of `cua-mode'.")
        (put 'cua-mode-line-format 'risky-local-variable t)
        (setq minor-mode-alist
    	  (append
    	   `((cua-mode " ") (cua-mode ,cua-mode-line-format))
    	   (delq (assq 'cua-mode minor-mode-alist) minor-mode-alist) ))
     
        ;; shift + click select region,用shift+鼠标选中,需要开启CUA(绑定到F2)
        (define-key global-map (kbd "") 'ignore) ; turn off font dialog
        (define-key global-map (kbd "") 'mouse-set-point)
        (put 'mouse-set-point 'CUA 'move)
        (setq cua-auto-tabify-rectangles nil) ;; Don't tabify after rectangle commands
        ;; (setq cua-keep-region-after-copy t) ;选中复制后保持选中状态
        ))
    (add-hook 'cua-mode-hook 'my-cua-mode-setting)

    [回复]

    ahei 回复:

    @lynn, 呵呵,弄好就好

    [回复]

  8. Wallace
    2011年4月22日23:54 | #8

    我也遇到了楼上kun的问题, 在windows下 启用 psvn 后 ,输入 svn-state ,指向的是有.svn 的目录, 但是却提示我 Searching for program: no such file or directory
    能不能研究一下是什么导致的,鼓捣了一天也没解决。郁闷。。。。。

    [回复]

  9. haiyehuo
    2014年2月17日18:12 | #9

    ralee也是emacs中的一个插件吧?但是我不知道如何将ralee安装上去。。可否教我下?非常感谢。。

    [回复]

  1. 2014年2月10日06:04 | #1
:wink: :-| :-x :twisted: :) 8-O :( :roll: :-P :oops: :-o :mrgreen: :lol: :idea: :-D :evil: :cry: 8) :arrow: :-? :?: :!: