graphviz是一个开源图形可视化软件,使用dot语言以文本形式描述图形,并提供工具将dot文件输出为图片。但如果使用vim编辑dot文件,可能会面临缩进格式错误的情况。主要原因是vim没有识别dot文件中port格式,而是默认按照label的方式缩进到行首。

比如以下错误缩进样式。

test.dot
1
2
3
4
5
6
7
8
9
10
11
12
13
digraph {
node [shape=record style=filled];

c [label="<c>c|{<p1>|<p2>}" fillcolor="#c1cbd7"];
a [color="#afb0b2"];
b [color="#c5b8a5"];
d [color="#8696a7"];

c:p1 -> a;
c:p2 -> b;
b -> d;
d -> c;
}

目前解决方式是增加一个vim配置文件,用于dot文件的缩进。

~/.vim/indent/dot.vim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
if exists("b:did_indent")
finish
endif

let b:did_indent = 1

setlocal cindent
setlocal indentexpr=GetDotIndent(v:lnum)

if exists("*GetDotIndent")
finish
endif

function GetDotIndent(lnum)
let prev = prevnonblank(a:lnum - 1)

if (cindent(a:lnum) == 0 && getline(a:lnum) =~ ":")
return indent(prev)
elseif (cindent(prev) == 0 && getline(prev) =~ ":" && cindent(a:lnum) > indent(prev))
return indent(prev)
end
return cindent(a:lnum)
endfunction

这时再使用vim自动格式化dot文件将会如我们预期。

test.dot
1
2
3
4
5
6
7
8
9
10
11
12
13
digraph {
node [shape=record style=filled];

c [label="<c>c|{<p1>|<p2>}" fillcolor="#c1cbd7"];
a [color="#afb0b2"];
b [color="#c5b8a5"];
d [color="#8696a7"];

c:p1 -> a;
c:p2 -> b;
b -> d;
d -> c;
}

顺便贴一下生成的图片。

graphviz生成图片

ps: dot文件格式行尾的分号是可选项,但是在行尾加入分号对缩进更友好。