Neovim高亮缩进线插件hlchunk

之前一直使用有名的高亮缩进插件indent-blankline.nvim , 同时也有一个专门用于配置indent-blankline彩虹缩进的插件indent-rainbowline. 但是自从昨天升级后发现这个插件报错,而且我也不愿意再消耗时间去修复这个bug, 于是经过搜索发现了另一个替代品hlchunk.nvim, 同时配置好以后发现还是挺好用的, 本文记录我的电脑配置以方便大众。

2024年05月31日, 由于官方对hlchunk.nvim做了大量更新,所以其配置相应发生变化,为了确保最新版本的使用,今天更新为可用的配置。

安装和配置

  1. Lazy.nvim中,找到文件~/.config/nvim/lua/lazy-init.lua, 然后添加

    1
    2
    3
    4
    {
    "shellRaining/hlchunk.nvim",
    event = { "BufReadPre", "BufNewFile" }
    },

  2. 编写配置文件~/.config/nvim/lua/plg/hlchunk.lua

    ~/.config/nvim/lua/plg/hlchunk.lua
    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
    #! /usr/bin/env lua
    -- hlchunk.lua
    -- https://fengzhenhua.gitlab.io/2024/05/18/Neovim高亮缩进线插件hlchunk
    -- Copyright (C) 2024 feng <feng@archlinux>
    --
    require('hlchunk').setup({
    blank = {
    enable = false,
    chars = {
    " ",
    },
    style = {
    { bg = "#434437" },
    { bg = "#2f4440" },
    { bg = "#433054" },
    { bg = "#284251" },
    },
    },
    chunk = {
    enable = true,
    chars = {
    horizontal_line = "─",
    vertical_line = "│",
    left_top = "┌",
    left_bottom = "└",
    right_arrow = "─",
    },
    style = "#00ffff",
    },
    indent = {
    enable = true,
    use_treesitter = false,
    -- chars = { "│", "¦", "┆", "┊", }, -- more code can be found in https://unicodeplus.com/
    chars = { "│" },
    style = {
    -- hlchunk 配色
    "#8B00FF",
    "#FF0000",
    "#FF7F00",
    "#FFFF00",
    "#00FF00",
    "#00FFFF",
    "#0000FF",
    "#8B00FF",
    -- indent-blankline 配色
    -- "#E06c75",
    -- "#E5C07B",
    -- "#61AFEF",
    -- "#D19A66",
    -- "#98C379",
    -- "#C678DD",
    -- "#56B6C2",
    -- "#8B00FF",
    },
    },
    line_num = {
    style = "#806d9c",
    priority = 10,
    use_treesitter = false,
    }
    })

  3. 启用hlchunk

    ~/.config/nvim/init.vim
    1
    lua require('plg/hlchunk')

官方仓库中的说明

blank

blank 可以用来做什么

我们代码的缩进一般是由空格或者 tab 组成的,因此可以在这些空位上动一些手脚,比如添加特殊字符表示这是一个空格,或者添加背景颜色,做出彩虹的效果。这个 mod 实质上继承自 indent,重写了 render 方法而已。

配置项

由于继承自 indent,他们的配置几乎相似和通用。blank mod 的默认配置如下:

1
2
3
4
local default_conf = {
priority = 9,
chars = { "․" },
}

chars 是一个 lua 表,其中的字符用来指示如何渲染 blank 字符,你可以设置为下面这样,来循环使用这些字符(尽管这样设置并不会很好看):

1
2
3
4
5
6
7
8
chars = {
" ",
"․",
"⁚",
"⁖",
"⁘",
"⁙",
},

style 继承自 indent,因此和 indent 的颜色实际上是一样的,并且配置方式一样。详情见 indent

example

下面是默认的 blank 样式

image

1
2
3
4
5
6
7
8
blank = {
chars = {
"․",
},
style = {
{ vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID("Whitespace")), "fg", "gui"), "" },
},
},

你也可以将空格设置的像是彩虹一般 🌈

screenshot
1
2
3
4
5
6
7
8
9
10
11
12
blank = {
enable = true,
chars = {
" ",
},
style = {
{ bg = "#434437" },
{ bg = "#2f4440" },
{ bg = "#433054" },
{ bg = "#284251" },
},
},

image

1
2
3
4
5
6
7
8
9
10
indent = {
chars = {
"․",
},
style = {
{ vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID("Whitespace")), "fg", "gui"), "" },
"#806d9c",
"#c06f98",
},
}

你也可以设置多种字符类型

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
indent = {
chars = {
"․",
"⁚",
"⁖",
"⁘",
"⁙",
},
style = {
"#666666",
"#555555",
"#444444",
},
}

最后,他还可以设置背景颜色

1
2
3
4
5
6
7
8
9
10
blank = {
enable = true,
chars = {
" ",
},
style = {
{ bg = vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID("cursorline")), "bg", "gui") },
{ bg = "", fg = "" },
},
}

chunk

chunk 用来做什么

这个 mod 可以用来指示当前光标所在的一个 chunk(比如 function_declaration,if_statement)等。并且提供了 textobject 方便你快速的操作这个 chunk。

配置项

该 mod 的默认配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
local default_conf = {
priority = 15,
style = {
{ fg = "#806d9c" },
{ fg = "#c21f30" },
},
use_treesitter = true,
chars = {
horizontal_line = "─",
vertical_line = "│",
left_top = "╭",
left_bottom = "╰",
right_arrow = ">",
},
textobject = "",
max_file_size = 1024 * 1024,
error_sign = true,
}

独有的配置项为 use_treesittercharstextobjectmax_file_sizeerror_sign

  • use_treesitter 是用来控制是否使用 treesitter 来高亮代码块,默认为 true。 如果该项被设置为 true,他是通过自底向上的查找树的节点,直至找到匹配的节点类型,以此获取相应的 chunk 范围的。而如果设置为 false,将使用 vim 的 searchpair 来查找最近的相邻大括号来推断位置(也因此导致 Python 等脚本语言无法正常使用该 mod)

  • chars 是一个表,其中的字符用来指示用哪些字符来渲染 chunk,这个表中包含五个部分

    • horizontal_line
    • vertical_line
    • left_top
    • left_bottom
    • right_arrow
  • textobject 是一个字符串,默认没有值。他用来表示想要用哪些字符来表示 textobject,比如我使用的就是 ic,意为 inner chunk,你也可以修改为其他顺手的字符

  • max_file_size 是一个数字,默认为 1MB,当打开的文件大小超过这个值时,将自动关闭该 mod

  • error_sign 是一个布尔值,默认为 true,如果你使用 treesitter 来高亮代码块,当遇到错误的代码块时,它将会把 chunk 的颜色设置为枫叶红(或者你想要的其他颜色),要启用这个选项,style 应该有两个颜色, 默认的 style 为

    1
    2
    3
    4
    style = {
    "#806d9c", -- 紫罗兰色
    "#c21f30", -- 枫叶红色
    },

对于通用的配置(在 README 中有提到),仅有部分需要特别注意:

  • style 是一个字符串或者 Lua 表。如果是字符串,必须是一个 RGB 十六进制字符串。如果是一个表,接收一到两个表示十六进制颜色的字符串,如果只有一个颜色,那么只会使用一个颜色来渲染 chunk,如果有两个颜色,那么会使用两个颜色来渲染 chunk,第一个颜色用来渲染正常的 chunk,第二个颜色用来渲染错误的 chunk。

除此之外,还可以使用这样的配置来动态的切换 chunk 的颜色,这是为了解决这个 issue

1
2
3
4
5
6
7
8
9
10
11
12
13
local cb = function()
if vim.g.colors_name == "tokyonight" then
return "#806d9c"
else
return "#00ffff"
end
end
chunk = {
style = {
{ fg = cb },
{ fg = "#f35336" },
},
},

example

下面是默认的 chunk 样式

image

他的配置方式为

1
2
3
4
5
6
7
8
9
10
chunk = {
chars = {
horizontal_line = "─",
vertical_line = "│",
left_top = "╭",
left_bottom = "╰",
right_arrow = ">",
},
style = "#806d9c",
},

你可以按照下面的配置来使你的样式看起来像是 GIF 里演示的那样

image

1
2
3
4
5
6
7
8
9
10
chunk = {
chars = {
horizontal_line = "─",
vertical_line = "│",
left_top = "┌",
left_bottom = "└",
right_arrow = "─",
},
style = "#00ffff",
},

indent

indent 用来做什么

我们写代码有时候会遇到嵌套很多层等情况,而为了确定某些代码是否在同一层级,我们需要缩进线来帮助定位。

配置项

该 mod 的默认配置如下:

1
2
3
4
5
6
7
local default_conf = {
priority = 10,
style = { vim.api.nvim_get_hl(0, { name = "Whitespace" }) },
use_treesitter = false,
chars = { "│" },
ahead_lines = 5,
}

独有的配置为 use_treesittercharsahead_lines

  • use_treesitter 是用来控制是否使用 treesitter 来判断 indent 的层数,默认为 false(因为性能问题)。如果你对缩进的精确要求很高,你可以尝试设置为 true,详情见这个 issue

  • chars 是一个表,其中的字符用来指示用什么字符来渲染 indent line,你可以尝试设置为下面这样:

    1
    2
    3
    4
    5
    6
    chars = {
    "│",
    "¦",
    "┆",
    "┊",
    },

实际渲染的时候,第一个层级会采用第一个字符,第二个层级会采用第二个字符,以此类推,如果层级超过了你设置的字符数,那么会循环使用这些字符。

  • ahead_lines 是一个数字,用来控制缩进线超前查看和渲染范围,默认为 5

和 chunk 一样,我们需要额外注意 style 这个通用配置:

  • 这里的 style 是一个 RGB 字符串或者一个表。如果是字符串,那么所有的缩进线将会采用这一种颜色来渲染,如果是表,可以有这两种写法:

    1
    2
    3
    4
    5
    style = {
    "#FF0000",
    "#FF7F00",
    "..."
    },

    或者

    1
    2
    3
    4
    5
    style = {
    { bg = "#FF0000", fg = "#FFFFFF" },
    { bg = "#FF7F00", fg = "FF7F00" },
    -- ...
    },

    如果你设置了背景颜色,那么缩进线将会采用背景颜色来渲染。

example

下面是默认的 indent 样式

image

1
2
3
4
5
6
7
8
indent = {
chars = {
"│",
},
style = {
vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID("Whitespace")), "fg", "gui"),
},
}

你也可以将缩进线设置的像是彩虹一般 🌈

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
indent = {
chars = {
"│",
},
style = {
"#FF0000",
"#FF7F00",
"#FFFF00",
"#00FF00",
"#00FFFF",
"#0000FF",
"#8B00FF",
},
}

你也可以设置多种字符类型

image

1
2
3
4
5
6
7
8
9
10
11
indent = {
chars = {
"│",
"¦",
"┆",
"┊",
},
style = {
vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID("Whitespace")), "fg", "gui"),
},
}

如果你喜欢更粗的显示效果,你可以设置渲染的背景颜色

image

1
2
3
4
5
6
7
8
9
10
11
indent = {
enable = true,
use_treesitter = false,
chars = {
" ",
},
style = {
{ bg = vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID("Whitespace")), "fg", "gui") },
},
exclude_filetype = exclude_ft,
}

line_num

line_num 用来做什么

其实他和 chunk 的功能相同,只是可能有些人不喜欢 chunk,偏好高亮行号的形式,因此有了这个 mod

配置项

该 mod 的默认配置如下:

1
2
3
4
5
local default_conf = {
style = "#806d9c",
priority = 10,
use_treesitter = false,
}

独有的配置项为 use_treesitter,用法和 chunk 的该项一样,详情见 chunk

和 chunk 一样,我们需要额外注意 style 这个通用配置:他只接收一个字符串,表示十六进制颜色,来表示行号的颜色

example

下面是默认的 line_num 样式

image

1
2
3
line_num = {
style = "#806d9c",
},
未来还会添加更多有意思的样式…… 如果你有好的想法,非常欢迎来提建议 😊