Skip to content

Commit b8ee8bc

Browse files
feat: configurable language border
## Details This change allows the user to configure how the space around the language (above a code block) is filled, allowing for the appearance of "tabs", rather than always having an even fill. Previously this was not supported because of all the potential edge cases around the language info section, user configuration, and overall configuration (like differences in concealing). To avoid all this complexity the implementation has been re-written to fully overlay the border lines, removing anything custom underneath the user may have set. This may cause problems for some obscure usage but I can't currently think of any. To continue supporting any potential additional info set in the language section (a not very popular feature but it exists), the info section is now added to the overlay. Two new features control this behavior, `code.language_info` decides whether to include the text in general (true by default), and `code.highlight_info` is the highlight used for that part of the virtual text. The main new option is `code.language_border`, which is the icon that will be used to fill in any additional space on the language info line. By default it is set to the full block character `█`, so when the highlight is applied it continues to look like the `thick` border style that was used before. To get something that looks more like a tab use the half block character `▄`. More options may be added in the future like a prefix and a suffix to further improve how border is rendered. There is an edge case for users who have set `code.highlight_border` to false, the `language_border` icon will get ignored and a space `' '` is used to fill the gaps instead. This is because any configured characters are unlikely to look good with the padding highlight applied to them. As a consequence of this updated behavior we no longer rely on `inline` virtual text to render the language, so neovim versions < `0.10.0` will now work with the left aligned language. While there might be some differences in behavior for some users, for the most part the defaults we are using should result in no visible changes out of the box. Co-authored-by: malasee <[email protected]>
1 parent 06a9e75 commit b8ee8bc

File tree

16 files changed

+224
-161
lines changed

16 files changed

+224
-161
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,8 @@ require('render-markdown').setup({
436436
language_icon = true,
437437
-- Whether to include the language name above code blocks.
438438
language_name = true,
439+
-- Whether to include the language info above code blocks.
440+
language_info = true,
439441
-- A list of language names for which background highlighting will be disabled.
440442
-- Likely because that language has background highlights itself.
441443
-- Use a boolean to make behavior apply to all languages.
@@ -463,6 +465,8 @@ require('render-markdown').setup({
463465
-- | thin | when lines are empty overlay the above & below icons |
464466
-- | hide | conceal lines unless language name or icon is added |
465467
border = 'hide',
468+
-- Used above code blocks to fill remaining space around language.
469+
language_border = '',
466470
-- Used above code blocks for thin border.
467471
above = '',
468472
-- Used below code blocks for thin border.
@@ -475,6 +479,8 @@ require('render-markdown').setup({
475479
inline_pad = 0,
476480
-- Highlight for code blocks.
477481
highlight = 'RenderMarkdownCode',
482+
-- Highlight for code info section, after the language.
483+
highlight_info = 'RenderMarkdownCodeInfo',
478484
-- Highlight for language, overrides icon provider value.
479485
highlight_language = nil,
480486
-- Highlight for border, use false to add no highlight.
@@ -1047,6 +1053,8 @@ require('render-markdown').setup({
10471053
language_icon = true,
10481054
-- Whether to include the language name above code blocks.
10491055
language_name = true,
1056+
-- Whether to include the language info above code blocks.
1057+
language_info = true,
10501058
-- A list of language names for which background highlighting will be disabled.
10511059
-- Likely because that language has background highlights itself.
10521060
-- Use a boolean to make behavior apply to all languages.
@@ -1074,6 +1082,8 @@ require('render-markdown').setup({
10741082
-- | thin | when lines are empty overlay the above & below icons |
10751083
-- | hide | conceal lines unless language name or icon is added |
10761084
border = 'hide',
1085+
-- Used above code blocks to fill remaining space around language.
1086+
language_border = '',
10771087
-- Used above code blocks for thin border.
10781088
above = '',
10791089
-- Used below code blocks for thin border.
@@ -1086,6 +1096,8 @@ require('render-markdown').setup({
10861096
inline_pad = 0,
10871097
-- Highlight for code blocks.
10881098
highlight = 'RenderMarkdownCode',
1099+
-- Highlight for code info section, after the language.
1100+
highlight_info = 'RenderMarkdownCodeInfo',
10891101
-- Highlight for language, overrides icon provider value.
10901102
highlight_language = nil,
10911103
-- Highlight for border, use false to add no highlight.
@@ -1547,6 +1559,7 @@ The table below shows all the highlight groups with their default link
15471559
| RenderMarkdownH5Bg | Visual | H5 background line |
15481560
| RenderMarkdownH6Bg | CursorColumn | H6 background line |
15491561
| RenderMarkdownCode | ColorColumn | Code block background |
1562+
| RenderMarkdownCodeInfo | @label | Code info, after language |
15501563
| RenderMarkdownCodeBorder | RenderMarkdownCode | Code border background |
15511564
| RenderMarkdownCodeFallback | Normal | Fallback for code language |
15521565
| RenderMarkdownCodeInline | RenderMarkdownCode | Inline code background |

doc/render-markdown.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,8 @@ Default Configuration ~
501501
language_icon = true,
502502
-- Whether to include the language name above code blocks.
503503
language_name = true,
504+
-- Whether to include the language info above code blocks.
505+
language_info = true,
504506
-- A list of language names for which background highlighting will be disabled.
505507
-- Likely because that language has background highlights itself.
506508
-- Use a boolean to make behavior apply to all languages.
@@ -528,6 +530,8 @@ Default Configuration ~
528530
-- | thin | when lines are empty overlay the above & below icons |
529531
-- | hide | conceal lines unless language name or icon is added |
530532
border = 'hide',
533+
-- Used above code blocks to fill remaining space around language.
534+
language_border = '█',
531535
-- Used above code blocks for thin border.
532536
above = '▄',
533537
-- Used below code blocks for thin border.
@@ -540,6 +544,8 @@ Default Configuration ~
540544
inline_pad = 0,
541545
-- Highlight for code blocks.
542546
highlight = 'RenderMarkdownCode',
547+
-- Highlight for code info section, after the language.
548+
highlight_info = 'RenderMarkdownCodeInfo',
543549
-- Highlight for language, overrides icon provider value.
544550
highlight_language = nil,
545551
-- Highlight for border, use false to add no highlight.
@@ -1106,6 +1112,8 @@ Code Block Configuration ~
11061112
language_icon = true,
11071113
-- Whether to include the language name above code blocks.
11081114
language_name = true,
1115+
-- Whether to include the language info above code blocks.
1116+
language_info = true,
11091117
-- A list of language names for which background highlighting will be disabled.
11101118
-- Likely because that language has background highlights itself.
11111119
-- Use a boolean to make behavior apply to all languages.
@@ -1133,6 +1141,8 @@ Code Block Configuration ~
11331141
-- | thin | when lines are empty overlay the above & below icons |
11341142
-- | hide | conceal lines unless language name or icon is added |
11351143
border = 'hide',
1144+
-- Used above code blocks to fill remaining space around language.
1145+
language_border = '█',
11361146
-- Used above code blocks for thin border.
11371147
above = '▄',
11381148
-- Used below code blocks for thin border.
@@ -1145,6 +1155,8 @@ Code Block Configuration ~
11451155
inline_pad = 0,
11461156
-- Highlight for code blocks.
11471157
highlight = 'RenderMarkdownCode',
1158+
-- Highlight for code info section, after the language.
1159+
highlight_info = 'RenderMarkdownCodeInfo',
11481160
-- Highlight for language, overrides icon provider value.
11491161
highlight_language = nil,
11501162
-- Highlight for border, use false to add no highlight.
@@ -1603,6 +1615,9 @@ The table below shows all the highlight groups with their default link
16031615
RenderMarkdownCode ColorColumn Code block
16041616
background
16051617

1618+
RenderMarkdownCodeInfo @label Code info, after
1619+
language
1620+
16061621
RenderMarkdownCodeBorder RenderMarkdownCode Code border
16071622
background
16081623

lua/render-markdown/config/code.lua

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,22 @@
55
---@field language_pad number
66
---@field language_icon boolean
77
---@field language_name boolean
8+
---@field language_info boolean
89
---@field disable_background boolean|string[]
910
---@field width render.md.code.Width
1011
---@field left_margin number
1112
---@field left_pad number
1213
---@field right_pad number
1314
---@field min_width integer
1415
---@field border render.md.code.Border
16+
---@field language_border string
1517
---@field above string
1618
---@field below string
1719
---@field inline_left string
1820
---@field inline_right string
1921
---@field inline_pad integer
2022
---@field highlight string
23+
---@field highlight_info string
2124
---@field highlight_language? string
2225
---@field highlight_border false|string
2326
---@field highlight_fallback string
@@ -79,6 +82,8 @@ M.default = {
7982
language_icon = true,
8083
-- Whether to include the language name above code blocks.
8184
language_name = true,
85+
-- Whether to include the language info above code blocks.
86+
language_info = true,
8287
-- A list of language names for which background highlighting will be disabled.
8388
-- Likely because that language has background highlights itself.
8489
-- Use a boolean to make behavior apply to all languages.
@@ -106,6 +111,8 @@ M.default = {
106111
-- | thin | when lines are empty overlay the above & below icons |
107112
-- | hide | conceal lines unless language name or icon is added |
108113
border = 'hide',
114+
-- Used above code blocks to fill remaining space around language.
115+
language_border = '',
109116
-- Used above code blocks for thin border.
110117
above = '',
111118
-- Used below code blocks for thin border.
@@ -118,6 +125,8 @@ M.default = {
118125
inline_pad = 0,
119126
-- Highlight for code blocks.
120127
highlight = 'RenderMarkdownCode',
128+
-- Highlight for code info section, after the language.
129+
highlight_info = 'RenderMarkdownCodeInfo',
121130
-- Highlight for language, overrides icon provider value.
122131
highlight_language = nil,
123132
-- Highlight for border, use false to add no highlight.
@@ -137,19 +146,22 @@ function M.validate(spec)
137146
spec:type('language_pad', 'number')
138147
spec:type('language_icon', 'boolean')
139148
spec:type('language_name', 'boolean')
149+
spec:type('language_info', 'boolean')
140150
spec:list('disable_background', 'string', 'boolean')
141151
spec:one_of('width', vim.tbl_values(Width))
142152
spec:type('left_margin', 'number')
143153
spec:type('left_pad', 'number')
144154
spec:type('right_pad', 'number')
145155
spec:type('min_width', 'number')
146156
spec:one_of('border', vim.tbl_values(Border))
157+
spec:type('language_border', 'string')
147158
spec:type('above', 'string')
148159
spec:type('below', 'string')
149160
spec:type('inline_left', 'string')
150161
spec:type('inline_right', 'string')
151162
spec:type('inline_pad', 'number')
152163
spec:type('highlight', 'string')
164+
spec:type('highlight_info', 'string')
153165
spec:type('highlight_language', { 'string', 'nil' })
154166
spec:one_of('highlight_border', { false }, 'string')
155167
spec:type('highlight_fallback', 'string')

lua/render-markdown/core/colors.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ M.colors = {
2525
H6Bg = 'CursorColumn',
2626
-- Code
2727
Code = 'ColorColumn',
28+
CodeInfo = '@label',
2829
CodeBorder = 'RenderMarkdownCode',
2930
CodeFallback = 'Normal',
3031
CodeInline = 'RenderMarkdownCode',

lua/render-markdown/health.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ local state = require('render-markdown.state')
55
local M = {}
66

77
---@private
8-
M.version = '8.5.5'
8+
M.version = '8.5.6'
99

1010
function M.check()
1111
M.start('version')

lua/render-markdown/init.lua

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,6 @@ function M.resolve_config(user)
130130
end
131131
-- override settings incompatible with neovim version with compatible alternatives
132132
local compat = require('render-markdown.lib.compat')
133-
if config.code.position == 'left' and not compat.has_10 then
134-
config.code.position = 'right'
135-
end
136133
if config.code.border == 'hide' and not compat.has_11 then
137134
config.code.border = 'thin'
138135
end

lua/render-markdown/lib/line.lua

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
local str = require('render-markdown.lib.str')
2+
13
---@class render.md.Line
24
---@field private highlight string
35
---@field private line render.md.mark.Line
@@ -23,6 +25,11 @@ function Line:empty()
2325
return #self.line == 0
2426
end
2527

28+
---@return integer
29+
function Line:width()
30+
return str.line_width(self.line)
31+
end
32+
2633
---@param other render.md.Line
2734
---@return render.md.Line
2835
function Line:extend(other)
@@ -44,8 +51,16 @@ end
4451
---@param highlight? render.md.mark.Hl
4552
---@return render.md.Line
4653
function Line:pad(n, highlight)
54+
return self:rep(' ', n, highlight)
55+
end
56+
57+
---@param s string
58+
---@param n integer
59+
---@param highlight? render.md.mark.Hl
60+
---@return render.md.Line
61+
function Line:rep(s, n, highlight)
4762
if n > 0 then
48-
self:add((' '):rep(n), highlight)
63+
self:add(s:rep(n), highlight)
4964
end
5065
return self
5166
end

0 commit comments

Comments
 (0)