Skip to content

Commit ff2fcd6

Browse files
fix: false positive link matching
## Details Issue: #650 Link matching logic is a simple pattern, but sometimes patterns can overmatch, in the report 'https://extranix.com/' matches the `x%.com` pattern which is incorrect. To fix this add a new pattern `kind` value `url`, most of the default patterns are now set to this `kind`, but the default behavior of `pattern` is kept to avoid breaking changes. With this new `kind` we still do a lua pattern match, but we pull out the prefix, meaning any text before the pattern starts. We then validate that this prefix looks like a valid url start, meaning it will match values like: - '' - 'http://' - 'https://' - 'http://www.' - 'https://www.' - 'www.' - 'https://www.blog.' However it will not match values like 'https://extrani'.
1 parent 3f3eea9 commit ff2fcd6

8 files changed

Lines changed: 132 additions & 108 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
- allow inline code left and right icon highlight to be specified [e9d7409](https://github.com/MeanderingProgrammer/render-markdown.nvim/commit/e9d7409c2d604dc12589c00ef922e08e3998e000)
88
- improve table start column tracking [2247dcd](https://github.com/MeanderingProgrammer/render-markdown.nvim/commit/2247dcd1ff0c223cfa7e317783f89b8d00457ce6)
99
- ability to not conceal wikilink destination when there is an alias [d67113f](https://github.com/MeanderingProgrammer/render-markdown.nvim/commit/d67113f11384c0dad96fced2f7b91f1fc811e97f)
10+
- configurable code block background inset [#643](https://github.com/MeanderingProgrammer/render-markdown.nvim/issues/643)
11+
[3f3eea9](https://github.com/MeanderingProgrammer/render-markdown.nvim/commit/3f3eea97b80839f629c951ca660ffd125bfa5b34)
1012

1113
### Bug Fixes
1214

README.md

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# render-markdown.nvim
22

3-
Plugin to improve viewing Markdown files in Neovim
3+
Improve viewing Markdown in Neovim
44

55
<!-- panvimdoc-ignore-start -->
66

@@ -836,33 +836,35 @@ require('render-markdown').setup({
836836
-- contains. Applies to 'image', 'inline_link', 'uri_autolink', and WikiLink nodes.
837837
-- When multiple patterns match a link the one with the longer pattern is used.
838838
-- The key is for healthcheck and to allow users to change its values, value type below.
839-
-- | pattern | matched against the destination text |
840839
-- | icon | gets inlined before the link text |
840+
-- | pattern | matched against the destination text |
841841
-- | kind | optional determines how pattern is checked |
842842
-- | | pattern | @see :h lua-patterns, is the default if not set |
843843
-- | | suffix | @see :h vim.endswith() |
844+
-- | | url | similar to pattern with additional prefix checks |
844845
-- | priority | optional used when multiple match, uses pattern length if empty |
845846
-- | highlight | optional highlight for 'icon', uses fallback highlight if empty |
847+
-- stylua: ignore
846848
custom = {
847-
web = { pattern = '^http', icon = '󰖟 ' },
848-
apple = { pattern = 'apple%.com', icon = '' },
849-
discord = { pattern = 'discord%.com', icon = '󰙯 ' },
850-
github = { pattern = 'github%.com', icon = '󰊤 ' },
851-
gitlab = { pattern = 'gitlab%.com', icon = '󰮠 ' },
852-
google = { pattern = 'google%.com', icon = '󰊭 ' },
853-
hackernews = { pattern = 'ycombinator%.com', icon = '' },
854-
linkedin = { pattern = 'linkedin%.com', icon = '󰌻 ' },
855-
microsoft = { pattern = 'microsoft%.com', icon = '' },
856-
neovim = { pattern = 'neovim%.io', icon = '' },
857-
reddit = { pattern = 'reddit%.com', icon = '󰑍 ' },
858-
slack = { pattern = 'slack%.com', icon = '󰒱 ' },
859-
stackoverflow = { pattern = 'stackoverflow%.com', icon = '󰓌 ' },
860-
steam = { pattern = 'steampowered%.com', icon = '' },
861-
twitter = { pattern = 'twitter%.com', icon = '' },
862-
wikipedia = { pattern = 'wikipedia%.org', icon = '󰖬 ' },
863-
x = { pattern = 'x%.com', icon = '' },
864-
youtube = { pattern = 'youtube[^.]*%.com', icon = '󰗃 ' },
865-
youtube_short = { pattern = 'youtu%.be', icon = '󰗃 ' },
849+
web = { icon = '󰖟 ', pattern = '^http' },
850+
apple = { icon = '', pattern = 'apple%.com', kind = 'url' },
851+
discord = { icon = '󰙯 ', pattern = 'discord%.com', kind = 'url' },
852+
github = { icon = '󰊤 ', pattern = 'github%.com', kind = 'url' },
853+
gitlab = { icon = '󰮠 ', pattern = 'gitlab%.com', kind = 'url' },
854+
google = { icon = '󰊭 ', pattern = 'google%.com', kind = 'url' },
855+
hackernews = { icon = '', pattern = 'ycombinator%.com', kind = 'url' },
856+
linkedin = { icon = '󰌻 ', pattern = 'linkedin%.com', kind = 'url' },
857+
microsoft = { icon = '', pattern = 'microsoft%.com', kind = 'url' },
858+
neovim = { icon = '', pattern = 'neovim%.io', kind = 'url' },
859+
reddit = { icon = '󰑍 ', pattern = 'reddit%.com', kind = 'url' },
860+
slack = { icon = '󰒱 ', pattern = 'slack%.com', kind = 'url' },
861+
stackoverflow = { icon = '󰓌 ', pattern = 'stackoverflow%.com', kind = 'url' },
862+
steam = { icon = '', pattern = 'steampowered%.com', kind = 'url' },
863+
twitter = { icon = '', pattern = 'twitter%.com', kind = 'url' },
864+
wikipedia = { icon = '󰖬 ', pattern = 'wikipedia%.org', kind = 'url' },
865+
x = { icon = '', pattern = 'x%.com', kind = 'url' },
866+
youtube = { icon = '󰗃 ', pattern = 'youtube[^.]*%.com', kind = 'url' },
867+
youtube_short = { icon = '󰗃 ', pattern = 'youtu%.be', kind = 'url' },
866868
},
867869
},
868870
sign = {
@@ -1639,33 +1641,35 @@ require('render-markdown').setup({
16391641
-- contains. Applies to 'image', 'inline_link', 'uri_autolink', and WikiLink nodes.
16401642
-- When multiple patterns match a link the one with the longer pattern is used.
16411643
-- The key is for healthcheck and to allow users to change its values, value type below.
1642-
-- | pattern | matched against the destination text |
16431644
-- | icon | gets inlined before the link text |
1645+
-- | pattern | matched against the destination text |
16441646
-- | kind | optional determines how pattern is checked |
16451647
-- | | pattern | @see :h lua-patterns, is the default if not set |
16461648
-- | | suffix | @see :h vim.endswith() |
1649+
-- | | url | similar to pattern with additional prefix checks |
16471650
-- | priority | optional used when multiple match, uses pattern length if empty |
16481651
-- | highlight | optional highlight for 'icon', uses fallback highlight if empty |
1652+
-- stylua: ignore
16491653
custom = {
1650-
web = { pattern = '^http', icon = '󰖟 ' },
1651-
apple = { pattern = 'apple%.com', icon = '' },
1652-
discord = { pattern = 'discord%.com', icon = '󰙯 ' },
1653-
github = { pattern = 'github%.com', icon = '󰊤 ' },
1654-
gitlab = { pattern = 'gitlab%.com', icon = '󰮠 ' },
1655-
google = { pattern = 'google%.com', icon = '󰊭 ' },
1656-
hackernews = { pattern = 'ycombinator%.com', icon = '' },
1657-
linkedin = { pattern = 'linkedin%.com', icon = '󰌻 ' },
1658-
microsoft = { pattern = 'microsoft%.com', icon = '' },
1659-
neovim = { pattern = 'neovim%.io', icon = '' },
1660-
reddit = { pattern = 'reddit%.com', icon = '󰑍 ' },
1661-
slack = { pattern = 'slack%.com', icon = '󰒱 ' },
1662-
stackoverflow = { pattern = 'stackoverflow%.com', icon = '󰓌 ' },
1663-
steam = { pattern = 'steampowered%.com', icon = '' },
1664-
twitter = { pattern = 'twitter%.com', icon = '' },
1665-
wikipedia = { pattern = 'wikipedia%.org', icon = '󰖬 ' },
1666-
x = { pattern = 'x%.com', icon = '' },
1667-
youtube = { pattern = 'youtube[^.]*%.com', icon = '󰗃 ' },
1668-
youtube_short = { pattern = 'youtu%.be', icon = '󰗃 ' },
1654+
web = { icon = '󰖟 ', pattern = '^http' },
1655+
apple = { icon = '', pattern = 'apple%.com', kind = 'url' },
1656+
discord = { icon = '󰙯 ', pattern = 'discord%.com', kind = 'url' },
1657+
github = { icon = '󰊤 ', pattern = 'github%.com', kind = 'url' },
1658+
gitlab = { icon = '󰮠 ', pattern = 'gitlab%.com', kind = 'url' },
1659+
google = { icon = '󰊭 ', pattern = 'google%.com', kind = 'url' },
1660+
hackernews = { icon = '', pattern = 'ycombinator%.com', kind = 'url' },
1661+
linkedin = { icon = '󰌻 ', pattern = 'linkedin%.com', kind = 'url' },
1662+
microsoft = { icon = '', pattern = 'microsoft%.com', kind = 'url' },
1663+
neovim = { icon = '', pattern = 'neovim%.io', kind = 'url' },
1664+
reddit = { icon = '󰑍 ', pattern = 'reddit%.com', kind = 'url' },
1665+
slack = { icon = '󰒱 ', pattern = 'slack%.com', kind = 'url' },
1666+
stackoverflow = { icon = '󰓌 ', pattern = 'stackoverflow%.com', kind = 'url' },
1667+
steam = { icon = '', pattern = 'steampowered%.com', kind = 'url' },
1668+
twitter = { icon = '', pattern = 'twitter%.com', kind = 'url' },
1669+
wikipedia = { icon = '󰖬 ', pattern = 'wikipedia%.org', kind = 'url' },
1670+
x = { icon = '', pattern = 'x%.com', kind = 'url' },
1671+
youtube = { icon = '󰗃 ', pattern = 'youtube[^.]*%.com', kind = 'url' },
1672+
youtube_short = { icon = '󰗃 ', pattern = 'youtu%.be', kind = 'url' },
16691673
},
16701674
},
16711675
})

doc/render-markdown.txt

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
*render-markdown.txt* For NVIM v0.12.1 Last change: 2026 April 26
1+
*render-markdown.txt* Improve viewing Markdown in Neovim
2+
For NVIM v0.12.2 Last change: 2026 May 07
23

34
==============================================================================
45
Table of Contents *render-markdown-table-of-contents*
@@ -39,7 +40,7 @@ Table of Contents *render-markdown-table-of-contents*
3940
==============================================================================
4041
1. render-markdown.nvim *render-markdown-render-markdown.nvim*
4142

42-
Plugin to improve viewing Markdown files in Neovim
43+
Improve viewing Markdown in Neovim
4344

4445

4546
==============================================================================
@@ -902,33 +903,35 @@ Default Configuration ~
902903
-- contains. Applies to 'image', 'inline_link', 'uri_autolink', and WikiLink nodes.
903904
-- When multiple patterns match a link the one with the longer pattern is used.
904905
-- The key is for healthcheck and to allow users to change its values, value type below.
905-
-- | pattern | matched against the destination text |
906906
-- | icon | gets inlined before the link text |
907+
-- | pattern | matched against the destination text |
907908
-- | kind | optional determines how pattern is checked |
908909
-- | | pattern | @see :h lua-patterns, is the default if not set |
909910
-- | | suffix | @see :h vim.endswith() |
911+
-- | | url | similar to pattern with additional prefix checks |
910912
-- | priority | optional used when multiple match, uses pattern length if empty |
911913
-- | highlight | optional highlight for 'icon', uses fallback highlight if empty |
914+
-- stylua: ignore
912915
custom = {
913-
web = { pattern = '^http', icon = '󰖟 ' },
914-
apple = { pattern = 'apple%.com', icon = '' },
915-
discord = { pattern = 'discord%.com', icon = '󰙯 ' },
916-
github = { pattern = 'github%.com', icon = '󰊤 ' },
917-
gitlab = { pattern = 'gitlab%.com', icon = '󰮠 ' },
918-
google = { pattern = 'google%.com', icon = '󰊭 ' },
919-
hackernews = { pattern = 'ycombinator%.com', icon = '' },
920-
linkedin = { pattern = 'linkedin%.com', icon = '󰌻 ' },
921-
microsoft = { pattern = 'microsoft%.com', icon = '' },
922-
neovim = { pattern = 'neovim%.io', icon = '' },
923-
reddit = { pattern = 'reddit%.com', icon = '󰑍 ' },
924-
slack = { pattern = 'slack%.com', icon = '󰒱 ' },
925-
stackoverflow = { pattern = 'stackoverflow%.com', icon = '󰓌 ' },
926-
steam = { pattern = 'steampowered%.com', icon = '' },
927-
twitter = { pattern = 'twitter%.com', icon = '' },
928-
wikipedia = { pattern = 'wikipedia%.org', icon = '󰖬 ' },
929-
x = { pattern = 'x%.com', icon = '' },
930-
youtube = { pattern = 'youtube[^.]*%.com', icon = '󰗃 ' },
931-
youtube_short = { pattern = 'youtu%.be', icon = '󰗃 ' },
916+
web = { icon = '󰖟 ', pattern = '^http' },
917+
apple = { icon = ' ', pattern = 'apple%.com', kind = 'url' },
918+
discord = { icon = '󰙯 ', pattern = 'discord%.com', kind = 'url' },
919+
github = { icon = '󰊤 ', pattern = 'github%.com', kind = 'url' },
920+
gitlab = { icon = '󰮠 ', pattern = 'gitlab%.com', kind = 'url' },
921+
google = { icon = '󰊭 ', pattern = 'google%.com', kind = 'url' },
922+
hackernews = { icon = ' ', pattern = 'ycombinator%.com', kind = 'url' },
923+
linkedin = { icon = '󰌻 ', pattern = 'linkedin%.com', kind = 'url' },
924+
microsoft = { icon = ' ', pattern = 'microsoft%.com', kind = 'url' },
925+
neovim = { icon = ' ', pattern = 'neovim%.io', kind = 'url' },
926+
reddit = { icon = '󰑍 ', pattern = 'reddit%.com', kind = 'url' },
927+
slack = { icon = '󰒱 ', pattern = 'slack%.com', kind = 'url' },
928+
stackoverflow = { icon = '󰓌 ', pattern = 'stackoverflow%.com', kind = 'url' },
929+
steam = { icon = ' ', pattern = 'steampowered%.com', kind = 'url' },
930+
twitter = { icon = ' ', pattern = 'twitter%.com', kind = 'url' },
931+
wikipedia = { icon = '󰖬 ', pattern = 'wikipedia%.org', kind = 'url' },
932+
x = { icon = ' ', pattern = 'x%.com', kind = 'url' },
933+
youtube = { icon = '󰗃 ', pattern = 'youtube[^.]*%.com', kind = 'url' },
934+
youtube_short = { icon = '󰗃 ', pattern = 'youtu%.be', kind = 'url' },
932935
},
933936
},
934937
sign = {
@@ -1685,33 +1688,35 @@ Link Configuration ~
16851688
-- contains. Applies to 'image', 'inline_link', 'uri_autolink', and WikiLink nodes.
16861689
-- When multiple patterns match a link the one with the longer pattern is used.
16871690
-- The key is for healthcheck and to allow users to change its values, value type below.
1688-
-- | pattern | matched against the destination text |
16891691
-- | icon | gets inlined before the link text |
1692+
-- | pattern | matched against the destination text |
16901693
-- | kind | optional determines how pattern is checked |
16911694
-- | | pattern | @see :h lua-patterns, is the default if not set |
16921695
-- | | suffix | @see :h vim.endswith() |
1696+
-- | | url | similar to pattern with additional prefix checks |
16931697
-- | priority | optional used when multiple match, uses pattern length if empty |
16941698
-- | highlight | optional highlight for 'icon', uses fallback highlight if empty |
1699+
-- stylua: ignore
16951700
custom = {
1696-
web = { pattern = '^http', icon = '󰖟 ' },
1697-
apple = { pattern = 'apple%.com', icon = '' },
1698-
discord = { pattern = 'discord%.com', icon = '󰙯 ' },
1699-
github = { pattern = 'github%.com', icon = '󰊤 ' },
1700-
gitlab = { pattern = 'gitlab%.com', icon = '󰮠 ' },
1701-
google = { pattern = 'google%.com', icon = '󰊭 ' },
1702-
hackernews = { pattern = 'ycombinator%.com', icon = '' },
1703-
linkedin = { pattern = 'linkedin%.com', icon = '󰌻 ' },
1704-
microsoft = { pattern = 'microsoft%.com', icon = '' },
1705-
neovim = { pattern = 'neovim%.io', icon = '' },
1706-
reddit = { pattern = 'reddit%.com', icon = '󰑍 ' },
1707-
slack = { pattern = 'slack%.com', icon = '󰒱 ' },
1708-
stackoverflow = { pattern = 'stackoverflow%.com', icon = '󰓌 ' },
1709-
steam = { pattern = 'steampowered%.com', icon = '' },
1710-
twitter = { pattern = 'twitter%.com', icon = '' },
1711-
wikipedia = { pattern = 'wikipedia%.org', icon = '󰖬 ' },
1712-
x = { pattern = 'x%.com', icon = '' },
1713-
youtube = { pattern = 'youtube[^.]*%.com', icon = '󰗃 ' },
1714-
youtube_short = { pattern = 'youtu%.be', icon = '󰗃 ' },
1701+
web = { icon = '󰖟 ', pattern = '^http' },
1702+
apple = { icon = ' ', pattern = 'apple%.com', kind = 'url' },
1703+
discord = { icon = '󰙯 ', pattern = 'discord%.com', kind = 'url' },
1704+
github = { icon = '󰊤 ', pattern = 'github%.com', kind = 'url' },
1705+
gitlab = { icon = '󰮠 ', pattern = 'gitlab%.com', kind = 'url' },
1706+
google = { icon = '󰊭 ', pattern = 'google%.com', kind = 'url' },
1707+
hackernews = { icon = ' ', pattern = 'ycombinator%.com', kind = 'url' },
1708+
linkedin = { icon = '󰌻 ', pattern = 'linkedin%.com', kind = 'url' },
1709+
microsoft = { icon = ' ', pattern = 'microsoft%.com', kind = 'url' },
1710+
neovim = { icon = ' ', pattern = 'neovim%.io', kind = 'url' },
1711+
reddit = { icon = '󰑍 ', pattern = 'reddit%.com', kind = 'url' },
1712+
slack = { icon = '󰒱 ', pattern = 'slack%.com', kind = 'url' },
1713+
stackoverflow = { icon = '󰓌 ', pattern = 'stackoverflow%.com', kind = 'url' },
1714+
steam = { icon = ' ', pattern = 'steampowered%.com', kind = 'url' },
1715+
twitter = { icon = ' ', pattern = 'twitter%.com', kind = 'url' },
1716+
wikipedia = { icon = '󰖬 ', pattern = 'wikipedia%.org', kind = 'url' },
1717+
x = { icon = ' ', pattern = 'x%.com', kind = 'url' },
1718+
youtube = { icon = '󰗃 ', pattern = 'youtube[^.]*%.com', kind = 'url' },
1719+
youtube_short = { icon = '󰗃 ', pattern = 'youtu%.be', kind = 'url' },
17151720
},
17161721
},
17171722
})

justfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ update:
88
python scripts/update.py
99
# https://github.com/kdheepak/panvimdoc
1010
../../../tools/panvimdoc/panvimdoc.sh \
11+
--input-file README.md \
1112
--project-name render-markdown \
12-
--input-file README.md
13+
--description "Improve viewing Markdown in Neovim"
1314

1415
check:
1516
selene --quiet .

lua/render-markdown/health.lua

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

88
---@private
9-
M.version = '8.12.12'
9+
M.version = '8.12.13'
1010

1111
function M.check()
1212
M.start('versions')

lua/render-markdown/lib/config.lua

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ function Config:set_link_text(destination, icon)
7171
local options = iter.table.filter(self.link.custom, function(custom)
7272
if custom.kind == 'suffix' then
7373
return vim.endswith(destination, custom.pattern)
74+
elseif custom.kind == 'url' then
75+
local prefix = destination:match('^(.*)' .. custom.pattern) ---@type string?
76+
if not prefix then
77+
return false
78+
end
79+
prefix = prefix:gsub('^https?://', '', 1)
80+
prefix = prefix:gsub('^www%.', '', 1)
81+
local last = prefix:sub(-1)
82+
return last == '' or last == '.'
7483
else
7584
return destination:find(custom.pattern) ~= nil
7685
end

0 commit comments

Comments
 (0)