V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
simple26
V2EX  ›  Vim

不用 vim-airline, 不用 lightline.vim, 如何使用纯手工制作一个与之媲美的 statusline

  •  1
     
  •   simple26 · 2016-12-27 23:13:33 +08:00 · 6073 次点击
    这是一个创建于 2888 天前的主题,其中的信息可能已经有所发展或是发生改变。

    首先看一下最后的效果:

    https://github.com/liuchengxu/space-vim/blob/master/docs/img/statusline.png

    知己知彼,百战不殆。先来分析一下使用 airline 与 lightline 有什么好处?

    1. 漂亮,酷炫,这毋庸置疑。
    2. airline 与很多插件集成的非常好,真是省心又省力。

    那有什么不足之处呢?

    1. airline 可能会导致 100 ms 的启动延迟。具体可以看这里 https://github.com/liuchengxu/space-vim/issues/24
    2. 定制性依旧不高,或者说深度定制的门槛有点高,不是那么容易上手。我曾经尝试过深入修改过 airline ,不过并不顺利。
    3. 它们所提供的信息可能过于庞杂,显得有些冗余。

    那么如何通过纯手工制作一个与 airline/lightline 相比也还不错的 statusline 呢?

    什么叫不错?这个因人而异,按照我个人的审美而言,首先不能太单调(我只关心漂不漂亮),其次得显示出一些有用的信息。那么就会涉及到以下一些内容:

    • 颜色转换,也就是各部分前景色,背景色之类的。
    • 一些有用的信息,比如语法检查的内容信息。

    为了漂亮,我们可能还会选择添加一些 Unicode 字符进去。

    function! Buf_total_num()
        return len(filter(range(1, bufnr('$')), 'buflisted(v:val)'))
    endfunction
    function! File_size(f)
        let l:size = getfsize(expand(a:f))
        if l:size == 0 || l:size == -1 || l:size == -2
            return ''
        endif
        if l:size < 1024
            return l:size.' bytes'
        elseif l:size < 1024*1024
            return printf('%.1f', l:size/1024.0).'k'
        elseif l:size < 1024*1024*1024
            return printf('%.1f', l:size/1024.0/1024.0) . 'm'
        else
            return printf('%.1f', l:size/1024.0/1024.0/1024.0) . 'g'
        endif
    endfunction
    set statusline=%<%1*[B-%n]%*
    " TOT is an abbreviation for total
    set statusline+=%2*[TOT:%{Buf_total_num()}]%*
    set statusline+=%3*\ %{File_size(@%)}\ %*
    set statusline+=%4*\ %F\ %*
    set statusline+=%5*『\ %{exists('g:loaded_ale')?ALEGetStatusLine():''}』%{exists('g:loaded_fugitive')?fugitive#statusline():''}%*
    set statusline+=%6*\ %m%r%y\ %*
    set statusline+=%=%7*\ %{&ff}\ \|\ %{\"\".(&fenc==\"\"?&enc:&fenc).((exists(\"+bomb\")\ &&\ &bomb)?\",B\":\"\").\"\ \|\"}\ %-14.(%l:%c%V%)%*
    set statusline+=%8*\ %P\ %*
    " default bg for statusline is 236 in space-vim-dark
    hi User1 cterm=bold ctermfg=232 ctermbg=179
    hi User2 cterm=None ctermfg=214 ctermbg=242
    hi User3 cterm=None ctermfg=251 ctermbg=240
    hi User4 cterm=bold ctermfg=169 ctermbg=239
    hi User5 cterm=None ctermfg=208 ctermbg=238
    hi User6 cterm=None ctermfg=246 ctermbg=237
    hi User7 cterm=None ctermfg=250 ctermbg=238
    hi User8 cterm=None ctermfg=249 ctermbg=240
    

    简单介绍一下重点:%1*[foo]%*, hi User1 ......, 改变的便是 [foo] 部分的 style, 比如前景色,背景色,粗体等等。如果你也想要尝试自己定制一番,按照个人喜好照葫芦画瓢即可 :p.

    顺便介绍一下 space-vim 的 statusline 值得关注的一些部分,[B-1] 代表 buffer 1, 1 为当前 buffer 对应的编号。[TOT 3], TOT 指的是 total, 当前共有多少 buffer ,可以使用 Tab 快速切换。 『 ... 』 这里面显示的是 ale 语法检查的信息。其他部分比较显然,值得关注的点也不多就不介绍了。

    末了,说一下上面的缺点:所有 window 的 statusline 都是很相似的,可能不能像 airline/lightline 那样容易区分出哪个是当前光标所在的 window 。 而且跟你的 colorscheme 可能不搭。不过我个人来讲,愿意接受这些不足。

    仅仅是分享一个方案,如何选择取决于你自己。

    第 1 条附言  ·  2016-12-28 00:37:23 +08:00
    上面的示例似乎有些复杂,下面给出一个 minimal version:

    ```
    set statusline+=%4*\ %F\ %*
    hi User4 cterm=bold ctermfg=169 ctermbg=239
    ```

    分两步:
    1. %+数字+* 后面跟上所要在 statusline 中显示的内容 +%*,圈出所要进行操作的范围, minimal version 中为 \ %F \ , 即为 空格 文件的全路径 空格。
    2. hi User 数字 cterm=bold ctermfg=111 ctermbg=111 gui=bold guifg=111 guibg=111 ,就会 highlight 上面圈出的范围。 cterm, gui 分别指的是 terminal 与 GUI 环境。 fg,bg 为前景,背景色。数字可以自己定义。 hi User1 ... 就会对 %1* ... %* 所圈中的 ... 进行 highlight 操作。

    至此你应该可以操作自己的 statusline 了。这里是 256 色对照表 http://www.calmar.ws/vim/256-xterm-24bit-rgb-color-chart.html

    再次说明,我只是分享一种方案,如何选择在于你自己。

    至于我为什么要分享?一来主要是为了锻炼自己 “讲故事” 的能力,能够简单地说明白一件事情是我所追求的目标。这一点我十分欣赏王垠,不论其他,他“讲故事”的能力我绝对服。二来是 make a reputation, 这一点不否认。
    第 2 条附言  ·  2016-12-28 08:25:16 +08:00
    也可以不用数字,采用自定义名称。

    比如%4* 可替换为%#highlightgroup#, highlightgroup 为一个自定义的名称,那么%4*\ %F\ %* 也可以写为 %#fullPath#\ %F\ %*, hi fullPath ... 进行 highlight 就可以了。
    29 条回复    2017-12-05 20:53:22 +08:00
    gfexfizv
        1
    gfexfizv  
       2016-12-27 23:16:55 +08:00 via iPhone
    我就想知道怎么改不发 staus line 的背景和前景颜色。能不能简单点说
    linboki
        2
    linboki  
       2016-12-27 23:21:01 +08:00
    大家看上 vim-airline 、 lightline.vim 的原因更重要是有人长期维护吧, lz 能保证维护个 3-5 年我就用你的
    simple26
        3
    simple26  
    OP
       2016-12-27 23:24:08 +08:00
    @gfexfizv 看 “简单说一下重点那一段”, 主要是使用 `%1* foo %*` 包裹住 foo, foo 比如说是 %n 即 buffer 编号,再使用 hi User1 ... 改变颜色之类, ctermfg ctermbg 很简单就是指的是 terminal 中的 前景色与背景色。其他照猫画虎即可。
    simple26
        4
    simple26  
    OP
       2016-12-27 23:30:24 +08:00
    @linboki 额,是否使用这个在于你的选择。我的本意在于分享一种解决方案,因为没有看到过有这样的内容。授人以鱼不如授人以渔,你完全可以写一个自己的 statusline, 最简单的比如说把我给出的示例颜色改改,显示的信息删删减减,然后这就是你自己的了。 理解这几行代码应该肯定不是问题。
    simple26
        5
    simple26  
    OP
       2016-12-27 23:33:32 +08:00
    chemzqm
        6
    chemzqm  
       2016-12-28 03:59:45 +08:00   ❤️ 1
    获取 git 分支信息需要系统调用一般会有 100ms 以上延迟,除非使用异步 API ,可参考 https://zhuanlan.zhihu.com/p/24484514 进行优化
    simple26
        7
    simple26  
    OP
       2016-12-28 07:32:37 +08:00
    @chemzqm 谢谢,目前还没有直观感受到这个操作带来的影响。

    不过您的启动优化的确非常好,我至今打开空文件都会超过 100ms, 可能在 150-200ms ,而您可以控制在 100ms 以内. 如果是打开涉及到插件比较多的文件,比如 python, 可能启动会更慢,超过 500ms. 但是目前我还没能想到能够进一步优化的方法,有时间会研究您的优化经验,感谢。
    rashawn
        8
    rashawn  
       2016-12-28 08:30:14 +08:00 via iPhone
    没记错的话 vim airline 的作者在用 emacs 吧
    simple26
        9
    simple26  
    OP
       2016-12-28 08:49:33 +08:00
    @rashawn 额,这个有关系吗?我也使用 spacemacs. 使用 emacs 对于他维护 airline 应该并不冲突...
    jsfaint
        10
    jsfaint  
       2016-12-28 10:02:46 +08:00
    @rashawn airline 是作者以前用 vim 的时候写的,他后来用 emacs 去了,就把维护交给社区了
    KentY
        11
    KentY  
       2016-12-28 18:22:59 +08:00
    我个人觉得那些各种 line 的状态条插件看着是挺好看, 但是大家用了千篇一律, 更重要的是, 为了美观还要去 hack 一些字体什么的, 有点舍本逐末. 状态栏是在编辑过程中提供一些自己认为必要的信息, 所以这是第一, 其次是装载以及更新速度, . 美观再次. 我也曾经随大流装过那些(当时可能是 powerline)插件,用了 1 个来小时, 就撤了. 目前用的还是自己配置的, 自己觉得也还算好看, 至少不算难看, 这个样子用了得有最少 3-5 年吧 呵呵:

    http://imgur.com/a/VuL7l

    其实, 颜色啊, 样式啊, 每个人都会多少花点时间在上面, 下面这个是按照我自己的 vim 情况配置的 tmux 的状态栏, 发帖时间看, 至少也有 2 年了.

    https://www.v2ex.com/t/154903#reply0
    KentY
        12
    KentY  
       2016-12-28 18:27:24 +08:00
    到底怎么直接贴图? 再试一个

    simple26
        13
    simple26  
    OP
       2016-12-28 19:31:18 +08:00
    @KentY 知道怎么处理以后剩下就是基本就是个人审美的诉求了 (偷偷告诉你,这招是看你的 vimrc 学来的,我之前不会设置 statusline 各部分的颜色...)

    再来试一下发图...

    http://www.liuchengxu.org/space-vim/img/statusline.png
    simple26
        14
    simple26  
    OP
       2016-12-28 19:33:06 +08:00
    ashfinal
        15
    ashfinal  
       2016-12-29 13:00:58 +08:00
    有个问题:使用 Tab 键切 Buf 不会把 Ctrl + I 快捷键给覆盖掉嘛?至少在终端里 Vim 不能区分这俩按键。不知楼主咋解决的?

    状态栏美化从开始到现在我一直用的 Airline 。主要是轻量不折腾,装上就能用。当时一看 powerline 还需要 patch 字体(就为了显示几个看上去很酷的符号?),还有巴拉巴拉不明所以的一堆,直接 pass 掉了。
    还有自动伸缩、主题切换等功能。主题切换可以和 Vim 的 Colorscheme 协同工作,当你发布某款 Colorscheme 时可附带个 Airline 主题。别人不需要再进行任何设置,当他切换 Colorscheme 的时候, Airline 主题也自动跟着变化。这样, Vim 整个外观( Tabline 、 Colorscheme 、状态栏、 CtrlP 、 CmdLine 等)就是浑然一体的,不会有什么不太和谐的部分。
    simple26
        16
    simple26  
    OP
       2016-12-29 13:14:03 +08:00
    @ashfinal 看了一下 CTRL-I , 看来我没有这个这个烦恼,因为我从来不用这个快捷键....

    airline 也是需要字体支持才能发挥其最佳效果的...

    主要是分享一种方案,优缺点我都已经说了,怎么选择是自己的个人喜好,自己开心就好。
    ashfinal
        17
    ashfinal  
       2016-12-29 14:40:40 +08:00
    @simple26 jumplist 对我来所还是挺重要的功能/快捷键。之前用 <Tab>、<S-Tab> 切换 buffer ,发现 <Tab> 不能用之后,还是稍微有点惆怅。。。

    嗯, airline 也支持 patch 字体。但个人喜好吧,觉得没有必要搞这个。
    当时 pass 掉 powerline 的主要原因是它太重了,文档太 TM 长了。而 airline 两分钟内就能明白怎么写自己的主题,怎么自定义区段等,提供的功能貌似也够用。

    纯手工写的 statusline ,这个其实非常适合无任何插件的 Vim ,在服务器上应急工作用。之前我也不知道咋设置 statusline 各部分的颜色呢,感谢楼主 🙏
    simple26
        18
    simple26  
    OP
       2016-12-29 15:45:38 +08:00
    @ashfinal 我搞这个主要是不想要 airline 那 100 ms 的延迟~
    rashawn
        19
    rashawn  
       2016-12-29 17:35:13 +08:00
    @simple26 当然没有关系....
    ashfinal
        20
    ashfinal  
       2016-12-30 13:37:15 +08:00
    @simple26 500 ms 以内的启动速度都可以接受, spacemacs 那至少 10 秒的启动速度才是真正让人心醉。。。
    simple26
        21
    simple26  
    OP
       2016-12-30 15:25:23 +08:00
    @ashfinal 也没那么夸张... spacemacs 我个人的启动时间一般是 5 6 秒

    关于 vim 的启动时间 你可以看一下 @chemzqm 给出的链接 相信如果你做不到他那样的优化的话 打开一个 400 行的文件时间通常会超过 500 ms
    ashfinal
        22
    ashfinal  
       2016-12-30 17:29:56 +08:00
    @simple26 难道有冷热启动之说?我一般刚退出再重启在 3.x s 的样子,但隔段时间启动印象中都是超过 10 s.

    vim 刚按照 @chemzqm 提供的方法试了下, 322 ms. 还行吧,没直观感受,懒得优化。

    最近得空看看 spacemacs ,挺好的发行版。就是我还什么都没做呢,就看到它启动加载了 207 个包!!!

    (˶‾᷄ ⁻̫ ‾᷅˵) 这要配置成完全顺手的,得多长时间呐?愁~ 有空就折腾折腾,没空先用 vim 吧。毕竟我的 .vimrc 文件才 800 行,刨除空行、注释、跨平台适配等一堆,也就 400 行左右?顶多一天就看完了(并完全理解了)。妈呀,还是有空再折腾 spacemacs 吧。●__●
    simple26
        23
    simple26  
    OP
       2016-12-30 17:57:17 +08:00
    @ashfinal 100 ms 的差距通常感觉不出来, 300 500 ms 一般就会有所察觉了... 我主要是针对一些影响比较大的插件手动加载,比如 ultisnips 和 YouCompleteMe, 并不依赖插件管理器自动加载。我的方式上面已经给出来了,如果你有更好的方式,一定要告诉我....

    哪那么有空.... 难道每天真的就是陪它们玩哈 :p ... spacemacs 能使用就行,深度定制这种事情还是有时间有心再说. 不过我个人的经验来说,就算默认的 spacemacs 也还不错,没什么“尴尬” 之处...., 毕竟有那么人在使用,在完善。
    ashfinal
        24
    ashfinal  
       2016-12-30 19:13:25 +08:00
    @simple26 我也没有哇 事实上根本没管。统共 26 个插件, 322 ms 。还行的样子?
    用的 plug.vim 管理,说是有懒加载。然而我根本没理,一概是“ Plug xxxx/xxx ”。

    刚把插件全禁了, 42 ms 。好吧 …… 插件影响还是有的。
    不过总体还行,等啥时候插件超过 50 个或者启动超过 1 s 再说了……

    spacemacs 挺好的,刚发现 Markdown 文档是支持行内图片预览的。这个好,不用多开预览器了。不过我最近正在转向 reST ,发现竟然不支持(反正还没搞定)。悲剧啊!(易中天脸

    得空再看看
    simple26
        25
    simple26  
    OP
       2017-01-12 21:26:41 +08:00
    @chemzqm let root = easygit#smartRoot(1) 想请教您这是什么意思?我找了一圈 easygit 没找到 easygit#smartRoot() 的定义...
    simple26
        27
    simple26  
    OP
       2017-01-12 21:56:30 +08:00
    @chemzqm 感谢,眼花了.....
    livc
        28
    livc  
       2017-12-05 14:56:20 +08:00
    > TOT 指的是 total, 当前共有多少 buffer,可以使用 Tab 快速切换。

    请问这个 tab 切换是你的 statusline 自带的功能吗,还是自己配?
    simple26
        29
    simple26  
    OP
       2017-12-05 20:53:22 +08:00
    @livc 自己配
    nnoremap <Tab> :bn<CR>
    nnoremap <S-Tab> :bp<CR>
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2814 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 09:34 · PVG 17:34 · LAX 01:34 · JFK 04:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.