diff --git a/README.md b/README.md
index 59bd961..c07afa7 100644
--- a/README.md
+++ b/README.md
@@ -63,6 +63,7 @@
@@ -80,6 +81,7 @@ Core features,
+ Highly customisable! You can change almost anything using the config!
+ Dynamic `highlight groups` that automatically updates with the colorscheme!
+ `Callout`, `checkbox` completions for `blink.cmp` & `nvim-cmp`.
++ Works with `tree-sitter injections` too!
@@ -104,6 +106,32 @@ Also see,
Expand to see complete feature list
+#### Fancy comments,
+
+

+
+> Comments are still experimental! The original parser only supports basic features.
+
+Conventional commit style comments with support for a subset of `markdown` & `vimdoc`. See [integrations#fancy-comments](https://github.com/OXY2DEV/markview.nvim/wiki/Integrations#-fancy-comments) For more info.
+
+Supported syntax,
+
++ Tasks(e.g. `feat`, `TODO` etc.)
++ Task scopes.
+
+Extra syntax(needs external parser),
+
++ `**Bold**`
++ `*Italic*`
++ `Code`
++ `'Quoted_text'`
++ `"Double quoted text"`
++ `@mentions`
++ `issues/reference#52`
++ `https://example.com`
++ `|help-section|`
++ Code blocks
+
#### HTML,

@@ -372,6 +400,7 @@ Parsers,
- `markdown`
- `markdown_inline`
+- `comment`(optional)
- `html`(optional)
- `latex`(optional)
- `typst`(optional)
diff --git a/doc/markview.nvim-comment.txt b/doc/markview.nvim-comment.txt
new file mode 100644
index 0000000..df8de5e
--- /dev/null
+++ b/doc/markview.nvim-comment.txt
@@ -0,0 +1,1197 @@
+*markview.nvim-comment* đ§© HTML options for `markview`
+
+demo {img:1}
+
+>lua
+ --[[ Configuration for `comments`. ]]
+ ---@class markview.config.comment
+ ---
+ ---@field enable boolean Enable **comment** rendering.
+ ---
+ ---@field autolinks markview.config.comment.autolinks
+ ---@field code_blocks markview.config.comment.code_blocks
+ ---@field inline_codes markview.config.comment.inline_codes
+ ---@field issues markview.config.comment.issues
+ ---@field mentions markview.config.comment.mentions
+ ---@field taglinks markview.config.comment.taglinks
+ ---@field tasks markview.config.comment.tasks
+ ---@field task_scopes markview.config.comment.task_scopes
+ ---@field urls markview.config.comment.urls
+<
+
+â  Warning
+â Fancy comments are experimental at the moment. Single line comments like
+â these,
+â
+>lua
+ -- feat: Some comment
+<
+
+â May not be correctly rendered when in large groups. Use multi-line
+â comments(e.g. `--[[ ... ]]`, `/* ... */`) for these.
+â This is a Neovim issue with tree-sitter injections in general and not a plugin
+â issue!
+
+--------------------------------------------------------------------------------
+enable *markview.nvim-comment.enable*
+
+>lua
+ enable = true
+<
+
+Enable rendering of fancy comments.
+
+--------------------------------------------------------------------------------
+autolinks *markview.nvim-comment.autolinks*
+
+>lua
+ --- Configuration for autolinks.
+ ---@class markview.config.comment.autolinks
+ ---
+ ---@field enable boolean Enable rendering of `
`s.
+ ---
+ ---@field default markview.config.comments.autolinks.opts Default configuration.
+ ---@field [string] markview.config.comments.autolinks.opts Configuration for autolinks matching the key's pattern.
+<
+
+Enable rendering of ``.
+
+See default ~
+configuration ~
+
+>lua
+ autolinks = {
+ enable = true,
+
+ default = {
+ icon = "ó°œ ",
+ hl = "MarkviewPalette6",
+ },
+
+ ---|fS
+
+ --NOTE(@OXY2DEV): Github sites.
+
+ ["github%.com/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com/
+ icon = "îȘ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return string.match(item.destination, "github%.com/([%a%d%-%_%.]+)%/?$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com//
+ icon = "ó°ł ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/?$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+/tree/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com///tree/
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ local repo, branch = string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)/tree/([%a%d%-%_%.]+)%/?$");
+ return repo .. " at " .. branch;
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+/commits/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com///commits/
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+/commits/[%a%d%-%_%.]+)%/?$");
+ end
+ },
+
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/releases$"] = {
+ --- github.com///releases
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Releases âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/releases$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/tags$"] = {
+ --- github.com///tags
+ icon = "ïŹ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Tags âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/tags$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/issues$"] = {
+ --- github.com///issues
+ icon = "îŹ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Issues âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/issues$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/pulls$"] = {
+ --- github.com///pulls
+ icon = "îŠ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Pull requests âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/pulls$");
+ end
+ },
+
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/wiki$"] = {
+ --- github.com///wiki
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Wiki âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/wiki$");
+ end
+ },
+
+ --- NOTE(@OXY2DEV): Commonly used sites by programmers.
+
+ ["developer%.mozilla%.org"] = {
+ priority = -9999,
+
+ icon = "ó° ",
+ hl = "MarkviewPalette5Fg"
+ },
+
+ ["w3schools%.com"] = {
+ priority = -9999,
+
+ icon = "î ",
+ hl = "MarkviewPalette4Fg"
+ },
+
+ ["stackoverflow%.com"] = {
+ priority = -9999,
+
+ icon = "ó° ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["reddit%.com"] = {
+ priority = -9999,
+
+ icon = "ïĄ ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["github%.com"] = {
+ priority = -9999,
+
+ icon = "îȘ ",
+ hl = "MarkviewPalette6Fg"
+ },
+
+ ["gitlab%.com"] = {
+ priority = -9999,
+
+ icon = "î« ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["dev%.to"] = {
+ priority = -9999,
+
+ icon = "ó±Ž ",
+ hl = "MarkviewPalette0Fg"
+ },
+
+ ["codepen%.io"] = {
+ priority = -9999,
+
+ icon = "ï ",
+ hl = "MarkviewPalette6Fg"
+ },
+
+ ["replit%.com"] = {
+ priority = -9999,
+
+ icon = "îą ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["jsfiddle%.net"] = {
+ priority = -9999,
+
+ icon = "ï ",
+ hl = "MarkviewPalette5Fg"
+ },
+
+ ["npmjs%.com"] = {
+ priority = -9999,
+
+ icon = "î ",
+ hl = "MarkviewPalette0Fg"
+ },
+
+ ["pypi%.org"] = {
+ priority = -9999,
+
+ icon = "ó°Š ",
+ hl = "MarkviewPalette0Fg"
+ },
+
+ ["mvnrepository%.com"] = {
+ priority = -9999,
+
+ icon = "îŽ ",
+ hl = "MarkviewPalette1Fg"
+ },
+
+ ["medium%.com"] = {
+ priority = -9999,
+
+ icon = "ïș ",
+ hl = "MarkviewPalette6Fg"
+ },
+
+ ["linkedin%.com"] = {
+ priority = -9999,
+
+ icon = "ó°» ",
+ hl = "MarkviewPalette5Fg"
+ },
+
+ ["news%.ycombinator%.com"] = {
+ priority = -9999,
+
+ icon = "ï ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["neovim%.io/doc/user/.*#%_?.*$"] = {
+ icon = "ïŻ ",
+ hl = "MarkviewPalette4Fg",
+
+ text = function (_, item)
+ local file, tag = string.match(item.destination, "neovim%.io/doc/user/(.*)#%_?(.*)$");
+ --- The actual website seems to show
+ --- _ in the site name so, we won't
+ --- be replacing `_`s with ` `s.
+ file = string.gsub(file, "%.html$", "");
+
+ return string.format("%s(%s) - Neovim docs", normalize_str(file), tag);
+ end
+ },
+ ["neovim%.io/doc/user/.*$"] = {
+ icon = "ïŻ ",
+ hl = "MarkviewPalette4Fg",
+
+ text = function (_, item)
+ local file = string.match(item.destination, "neovim%.io/doc/user/(.*)$");
+ file = string.gsub(file, "%.html$", "");
+
+ return string.format("%s - Neovim docs", normalize_str(file));
+ end
+ },
+
+ ["github%.com/vim/vim"] = {
+ priority = -100,
+
+ icon = "î
",
+ hl = "MarkviewPalette4Fg",
+ },
+
+ ["github%.com/neovim/neovim"] = {
+ priority = -100,
+
+ icon = "ïŻ ",
+ hl = "MarkviewPalette4Fg",
+ },
+
+ ["vim%.org"] = {
+ icon = "î
",
+ hl = "MarkviewPalette4Fg",
+ },
+
+ ["luals%.github%.io/wiki/?.*$"] = {
+ icon = "î ",
+ hl = "MarkviewPalette5Fg",
+
+ text = function (_, item)
+ if string.match(item.destination, "luals%.github%.io/wiki/(.-)/#(.+)$") then
+ local page_mappings = {
+ annotations = {
+ ["as"] = "@as",
+ ["alias"] = "@alias",
+ ["async"] = "@async",
+ ["cast"] = "@cast",
+ ["class"] = "@class",
+ ["deprecated"] = "@deprecated",
+ ["diagnostic"] = "@diagnostic",
+ ["enum"] = "@enum",
+ ["field"] = "@field",
+ ["generic"] = "@generic",
+ ["meta"] = "@meta",
+ ["module"] = "@module",
+ ["nodiscard"] = "@nodiscard",
+ ["operator"] = "@operator",
+ ["overload"] = "@overload",
+ ["package"] = "@package",
+ ["param"] = "@param",
+ ["see"] = "@see",
+ ["source"] = "@source",
+ ["type"] = "@type",
+ ["vaarg"] = "@vaarg",
+ ["version"] = "@version"
+ }
+ };
+
+ local page, section = string.match(item.destination, "luals%.github%.io/wiki/(.-)/#(.+)$");
+
+ if page_mappings[page] and page_mappings[page][section] then
+ section = page_mappings[page][section];
+ else
+ section = normalize_str(string.gsub(section, "%-", " "));
+ end
+
+ return string.format("%s(%s) | Lua Language Server", normalize_str(page), section);
+ elseif string.match(item.destination, "") then
+ local page = string.match(item.destination, "luals%.github%.io/wiki/(.-)/?$");
+
+ return string.format("%s | Lua Language Server", normalize_str(page));
+ else
+ return item.destination;
+ end
+ end
+ },
+
+ ---|fE
+ },
+<
+
+Each autolink type has the following options.
+
+>lua
+ ---@class markview.config.comments.autolinks.opts
+ ---
+ ---@field corner_left? string Left corner.
+ ---@field corner_left_hl? string Highlight group for the left corner.
+ ---
+ ---@field padding_left? string Left padding(added after `corner_left`).
+ ---@field padding_left_hl? string Highlight group for the left padding.
+ ---
+ ---@field icon? string Icon(added after `padding_left`).
+ ---@field icon_hl? string Highlight group for the icon.
+ ---
+ --[[ Text to show instead of the `autolink`.]]
+ ---@field text?
+ ---| string
+ ---| function(buffer: integer, item: markview.parsed.comment.autolinks): string
+ ---@field text_hl? string Highlight group for the shown text.
+ ---
+ ---@field hl? string Default highlight group(used by `*_hl` options when they are not set).
+ ---
+ ---@field padding_right? string Right padding.
+ ---@field padding_right_hl? string Highlight group for the right padding.
+ ---
+ ---@field corner_right? string Right corner(added after `padding_right`).
+ ---@field corner_right_hl? string Highlight group for the right corner.
+<
+
+--------------------------------------------------------------------------------
+code_blocks *markview.nvim-comment.code_blocks*
+
+>lua
+ --- Configuration for autolinks.
+ ---@class markview.config.comment.autolinks
+ ---
+ ---@field enable boolean Enable rendering of ``s.
+ ---
+ ---@field default markview.config.comments.autolinks.opts Default configuration.
+ ---@field [string] markview.config.comments.autolinks.opts Configuration for autolinks matching the key's pattern.
+<
+
+Enable rendering of `fenced code blocks`.
+
+See default ~
+configuration ~
+
+>lua
+ code_blocks = {
+ enable = true,
+
+ border_hl = "MarkviewCode",
+ info_hl = "MarkviewCodeInfo",
+
+ label_direction = "right",
+ label_hl = nil,
+
+ min_width = 60,
+ pad_amount = 2,
+ pad_char = " ",
+
+ default = {
+ block_hl = "MarkviewCode",
+ pad_hl = "MarkviewCode"
+ },
+
+ ["diff"] = {
+ block_hl = function (_, line)
+ if line:match("^%+") then
+ return "MarkviewPalette4";
+ elseif line:match("^%-") then
+ return "MarkviewPalette1";
+ else
+ return "MarkviewCode";
+ end
+ end,
+ pad_hl = "MarkviewCode"
+ },
+
+ style = "block",
+ sign = true,
+ },
+<
+
+--------------------------------------------------------------------------------
+inline_codes *markview.nvim-comment.inline_codes*
+
+>lua
+ --- Configuration for autolinks.
+ ---@class markview.config.comment.autolinks
+ ---
+ ---@field enable boolean Enable rendering of ``s.
+ ---
+ ---@field default markview.config.comments.autolinks.opts Default configuration.
+ ---@field [string] markview.config.comments.autolinks.opts Configuration for autolinks matching the key's pattern.
+<
+
+Enable rendering of `inline codes`.
+
+See default ~
+configuration ~
+
+>lua
+ inline_codes = {
+ padding_left = " ",
+ padding_right = " ",
+
+ hl = "MarkviewInlineCode",
+ },
+<
+
+--------------------------------------------------------------------------------
+issues *markview.nvim-comment.issues*
+
+>lua
+ --- Configuration for issues.
+ ---@class markview.config.comment.issues
+ ---
+ ---@field enable boolean Enable rendering of `#issue`s.
+ ---
+ ---@field default markview.config.__inline Default configuration for issues.
+ ---@field [string] markview.config.__inline Configuration for issues whose text matches with the key's pattern.
+<
+
+Enable rendering of `inline codes`.
+
+See default ~
+configuration ~
+
+>lua
+ issues = {
+ enable = true,
+
+ default = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "îŹ ",
+
+ hl = "MarkviewPalette2",
+ },
+ },
+<
+
+Each issue type has inline options {1}, unless explicitly mentioned otherwise.
+
+--------------------------------------------------------------------------------
+mentions *markview.nvim-comment.mentions*
+
+>lua
+ --- Configuration for mentions.
+ ---@class markview.config.comment.mentions
+ ---
+ ---@field enable boolean Enable rendering of `@mention`s.
+ ---
+ ---@field default markview.config.__inline Default configuration for mentions.
+ ---@field [string] markview.config.__inline Configuration for mentions whose text matches with the key's pattern.
+<
+
+Enable rendering of `@mentions`.
+
+See default ~
+configuration ~
+
+>lua
+ mentions = {
+ enable = true,
+
+ default = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ï ",
+
+ hl = "MarkviewPalette5",
+ },
+ },
+<
+
+Each mention type has inline options {2}, unless explicitly mentioned otherwise.
+
+--------------------------------------------------------------------------------
+taglinks *markview.nvim-comment.taglinks*
+
+>lua
+ --- Configuration for taglinks.
+ ---@class markview.config.comment.taglinks
+ ---
+ ---@field enable boolean Enable rendering of `|taglink|`s.
+ ---
+ ---@field default markview.config.__inline Default configuration.
+ ---@field [string] markview.config.__inline Configuration for taglinks matching the key's pattern.
+<
+
+Enable rendering of `|taglinks|`.
+
+See default ~
+configuration ~
+
+>lua
+ taglinks = {
+ enable = true,
+
+ default = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°· ",
+
+ hl = "MarkviewHyperlink",
+ },
+ },
+<
+
+Each taglink type has inline options {3}, unless explicitly mentioned otherwise.
+
+--------------------------------------------------------------------------------
+tasks *markview.nvim-comment.tasks*
+
+>lua
+ ---@class markview.config.comment.tasks
+ ---
+ ---@field enable boolean
+ ---
+ ---@field default markview.config.comment.tasks.opts
+ ---@field [string] markview.config.comment.tasks.opts
+<
+
+Enable rendering of `tasks`.
+
+See default ~
+configuration ~
+
+>lua
+ tasks = {
+ enable = true,
+
+ default = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°° ",
+
+ hl = "MarkviewPalette1",
+ },
+
+ ["^feat"] = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó±
",
+
+ hl = "MarkviewPalette7",
+ },
+
+ praise = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó±„ ",
+
+ hl = "MarkviewPalette3",
+ },
+
+ ["^suggest"] = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°Ł ",
+
+ hl = "MarkviewPalette2",
+ },
+
+ thought = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°§ ",
+
+ hl = "MarkviewPalette0",
+ },
+
+ note = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó° ź ",
+
+ hl = "MarkviewPalette5",
+ },
+
+ ["^info"] = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°Œ ",
+
+ hl = "MarkviewPalette0",
+ },
+
+ xxx = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°œ ",
+
+ hl = "MarkviewPalette0",
+ },
+
+ ["^nit"] = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°©° ",
+
+ hl = "MarkviewPalette6",
+ },
+
+ ["^warn"] = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = " ",
+
+ hl = "MarkviewPalette3",
+ },
+
+ fix = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°š ",
+
+ hl = "MarkviewPalette7",
+ },
+
+ hack = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó± ",
+
+ hl = "MarkviewPalette1",
+ },
+
+ typo = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ïš ",
+
+ hl = "MarkviewPalette0",
+ },
+
+ wip = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°Š ",
+
+ hl = "MarkviewPalette2",
+ },
+
+ issue = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "îŹ ",
+
+ hl = "MarkviewPalette1",
+ },
+
+ ["error"] = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°
",
+
+ hl = "MarkviewPalette1",
+ },
+
+ fixme = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°¶Ż ",
+
+ hl = "MarkviewPalette4",
+ },
+
+ deprecated = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°© ",
+
+ hl = "MarkviewPalette1",
+ },
+ },
+<
+
+Each task type has inline options {4}, unless explicitly mentioned otherwise.
+
+--------------------------------------------------------------------------------
+task_scopes *markview.nvim-comment.task_scopes*
+
+>lua
+ --- Configuration for task_scopes.
+ ---@class markview.config.comment.task_scopes
+ ---
+ ---@field enable boolean Enable rendering of `task scope`s.
+ ---
+ ---@field default markview.config.__inline Default configuration for mentions.
+ ---@field [string] markview.config.__inline Configuration for scopes matching the key's pattern.
+<
+
+Enable rendering of `task_scopes`.
+
+See default ~
+configuration ~
+
+>lua
+ task_scopes = {
+ enable = true,
+
+ default = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°Č ",
+
+ hl = "MarkviewPalette4",
+ },
+ },
+<
+
+Each task scope type has inline options {5}, unless explicitly mentioned
+otherwise.
+
+--------------------------------------------------------------------------------
+urls *markview.nvim-comment.urls*
+
+>lua
+ --- Configuration for URLs.
+ ---@class markview.config.comment.urls
+ ---
+ ---@field enable boolean Enable rendering of `URL`s.
+ ---
+ ---@field default markview.config.comments.urls.opts Default configuration for URLs.
+ ---@field [string] markview.config.comments.urls.opts Configuration for URLs whose text matches with the key's pattern.
+<
+
+Enable rendering of `urls`.
+
+See default ~
+configuration ~
+
+>lua
+ urls = {
+ enable = true,
+
+ default = {
+ icon = "ó°· ",
+
+ hl = "MarkviewHyperlink",
+ },
+
+ ---|fS
+
+ --NOTE(@OXY2DEV): Github sites.
+
+ ["github%.com/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com/
+ icon = "îȘ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return string.match(item.destination, "github%.com/([%a%d%-%_%.]+)%/?$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com//
+ icon = "ó°ł ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/?$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+/tree/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com///tree/
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ local repo, branch = string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)/tree/([%a%d%-%_%.]+)%/?$");
+ return repo .. " at " .. branch;
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+/commits/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com///commits/
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+/commits/[%a%d%-%_%.]+)%/?$");
+ end
+ },
+
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/releases$"] = {
+ --- github.com///releases
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Releases âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/releases$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/tags$"] = {
+ --- github.com///tags
+ icon = "ïŹ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Tags âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/tags$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/issues$"] = {
+ --- github.com///issues
+ icon = "îŹ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Issues âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/issues$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/pulls$"] = {
+ --- github.com///pulls
+ icon = "îŠ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Pull requests âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/pulls$");
+ end
+ },
+
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/wiki$"] = {
+ --- github.com///wiki
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Wiki âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/wiki$");
+ end
+ },
+
+ --- NOTE(@OXY2DEV): Commonly used sites by programmers.
+
+ ["developer%.mozilla%.org"] = {
+ priority = -9999,
+
+ icon = "ó° ",
+ hl = "MarkviewPalette5Fg"
+ },
+
+ ["w3schools%.com"] = {
+ priority = -9999,
+
+ icon = "î ",
+ hl = "MarkviewPalette4Fg"
+ },
+
+ ["stackoverflow%.com"] = {
+ priority = -9999,
+
+ icon = "ó° ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["reddit%.com"] = {
+ priority = -9999,
+
+ icon = "ïĄ ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["github%.com"] = {
+ priority = -9999,
+
+ icon = "îȘ ",
+ hl = "MarkviewPalette6Fg"
+ },
+
+ ["gitlab%.com"] = {
+ priority = -9999,
+
+ icon = "î« ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["dev%.to"] = {
+ priority = -9999,
+
+ icon = "ó±Ž ",
+ hl = "MarkviewPalette0Fg"
+ },
+
+ ["codepen%.io"] = {
+ priority = -9999,
+
+ icon = "ï ",
+ hl = "MarkviewPalette6Fg"
+ },
+
+ ["replit%.com"] = {
+ priority = -9999,
+
+ icon = "îą ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["jsfiddle%.net"] = {
+ priority = -9999,
+
+ icon = "ï ",
+ hl = "MarkviewPalette5Fg"
+ },
+
+ ["npmjs%.com"] = {
+ priority = -9999,
+
+ icon = "î ",
+ hl = "MarkviewPalette0Fg"
+ },
+
+ ["pypi%.org"] = {
+ priority = -9999,
+
+ icon = "ó°Š ",
+ hl = "MarkviewPalette0Fg"
+ },
+
+ ["mvnrepository%.com"] = {
+ priority = -9999,
+
+ icon = "îŽ ",
+ hl = "MarkviewPalette1Fg"
+ },
+
+ ["medium%.com"] = {
+ priority = -9999,
+
+ icon = "ïș ",
+ hl = "MarkviewPalette6Fg"
+ },
+
+ ["linkedin%.com"] = {
+ priority = -9999,
+
+ icon = "ó°» ",
+ hl = "MarkviewPalette5Fg"
+ },
+
+ ["news%.ycombinator%.com"] = {
+ priority = -9999,
+
+ icon = "ï ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["neovim%.io/doc/user/.*#%_?.*$"] = {
+ icon = "ïŻ ",
+ hl = "MarkviewPalette4Fg",
+
+ text = function (_, item)
+ local file, tag = string.match(item.destination, "neovim%.io/doc/user/(.*)#%_?(.*)$");
+ --- The actual website seems to show
+ --- _ in the site name so, we won't
+ --- be replacing `_`s with ` `s.
+ file = string.gsub(file, "%.html$", "");
+
+ return string.format("%s(%s) - Neovim docs", normalize_str(file), tag);
+ end
+ },
+ ["neovim%.io/doc/user/.*$"] = {
+ icon = "ïŻ ",
+ hl = "MarkviewPalette4Fg",
+
+ text = function (_, item)
+ local file = string.match(item.destination, "neovim%.io/doc/user/(.*)$");
+ file = string.gsub(file, "%.html$", "");
+
+ return string.format("%s - Neovim docs", normalize_str(file));
+ end
+ },
+
+ ["github%.com/vim/vim"] = {
+ priority = -100,
+
+ icon = "î
",
+ hl = "MarkviewPalette4Fg",
+ },
+
+ ["github%.com/neovim/neovim"] = {
+ priority = -100,
+
+ icon = "ïŻ ",
+ hl = "MarkviewPalette4Fg",
+ },
+
+ ["vim%.org"] = {
+ icon = "î
",
+ hl = "MarkviewPalette4Fg",
+ },
+
+ ["luals%.github%.io/wiki/?.*$"] = {
+ icon = "î ",
+ hl = "MarkviewPalette5Fg",
+
+ text = function (_, item)
+ if string.match(item.destination, "luals%.github%.io/wiki/(.-)/#(.+)$") then
+ local page_mappings = {
+ annotations = {
+ ["as"] = "@as",
+ ["alias"] = "@alias",
+ ["async"] = "@async",
+ ["cast"] = "@cast",
+ ["class"] = "@class",
+ ["deprecated"] = "@deprecated",
+ ["diagnostic"] = "@diagnostic",
+ ["enum"] = "@enum",
+ ["field"] = "@field",
+ ["generic"] = "@generic",
+ ["meta"] = "@meta",
+ ["module"] = "@module",
+ ["nodiscard"] = "@nodiscard",
+ ["operator"] = "@operator",
+ ["overload"] = "@overload",
+ ["package"] = "@package",
+ ["param"] = "@param",
+ ["see"] = "@see",
+ ["source"] = "@source",
+ ["type"] = "@type",
+ ["vaarg"] = "@vaarg",
+ ["version"] = "@version"
+ }
+ };
+
+ local page, section = string.match(item.destination, "luals%.github%.io/wiki/(.-)/#(.+)$");
+
+ if page_mappings[page] and page_mappings[page][section] then
+ section = page_mappings[page][section];
+ else
+ section = normalize_str(string.gsub(section, "%-", " "));
+ end
+
+ return string.format("%s(%s) | Lua Language Server", normalize_str(page), section);
+ elseif string.match(item.destination, "") then
+ local page = string.match(item.destination, "luals%.github%.io/wiki/(.-)/?$");
+
+ return string.format("%s | Lua Language Server", normalize_str(page));
+ else
+ return item.destination;
+ end
+ end
+ },
+
+ ---|fE
+ },
+<
+
+Each URL type has inline options {6}, unless explicitly mentioned otherwise.
+
+ â¶âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââŽ
+
+--------------------------------------------------------------------------------
+Inline syntax
+
+Inline elements support most of these options.
+
+>lua
+ ---@class markview.config.__inline
+ ---
+ ---@field enable? boolean Only valid if it's a top level option, Used for disabling previews.
+ ---@field virtual? boolean In `inline_codes`, when `true` masks the text with a virtual text(useful if the line has a background).
+ ---
+ ---@field corner_left? string Left corner.
+ ---@field corner_left_hl? string Highlight group for the left corner.
+ ---
+ ---@field padding_left? string Left padding(added after `corner_left`).
+ ---@field padding_left_hl? string Highlight group for the left padding.
+ ---
+ ---@field icon? string Icon(added after `padding_left`).
+ ---@field icon_hl? string Highlight group for the icon.
+ ---
+ ---@field hl? string Default highlight group(used by `*_hl` options when they are not set).
+ ---
+ ---@field padding_right? string Right padding.
+ ---@field padding_right_hl? string Highlight group for the right padding.
+ ---
+ ---@field corner_right? string Right corner(added after `padding_right`).
+ ---@field corner_right_hl? string Highlight group for the right corner.
+ ---
+ ---
+ ---
+ ---@field block_hl? string Only for `block_references`, highlight group for the block name.
+ ---@field file_hl? string Only for `block_references`, highlight group for the file name.
+<
+
+Links ~
+
+1: #inline-syntax
+2: #inline-syntax
+3: #inline-syntax
+4: #inline-syntax
+5: #inline-syntax
+6: #inline-syntax
+
+Images ~
+
+1: ./images/comment/markview.nvim-comment.injection.png
+
+vim:ft=help:textwidth=80:tabstop=4:noexpandtab:
diff --git a/doc/markview.nvim-experimental.txt b/doc/markview.nvim-experimental.txt
index bd87639..ed7937d 100644
--- a/doc/markview.nvim-experimental.txt
+++ b/doc/markview.nvim-experimental.txt
@@ -4,6 +4,8 @@
--- Experimental options.
---@class markview.config.experimental
---
+ ---@field fancy_comments boolean When `true`, enables preview on **all buffers** with an active `tree-sitter parser`.
+ ---
---@field date_formats string[] List of lua patterns for detecting date in YAML.
---@field date_time_formats string[] List of lua patterns for detecting date & time in YAML.
---
@@ -17,6 +19,12 @@
---@field linewise_ignore_org_indent? boolean Prevents indentation of sections from being cleared in `linewise_hybrid_mode`.
<
+--------------------------------------------------------------------------------
+fancy_comments *markview.nvim-experimental.fancy_comments*
+
+When true enables `fancy comment rendering`. See [integrations#fancy_comments]()
+for more information.
+
--------------------------------------------------------------------------------
date_formats *markview.nvim-experimental.date_formats*
diff --git a/doc/markview.nvim-integrations.txt b/doc/markview.nvim-integrations.txt
index bdc6f90..a21d3b6 100644
--- a/doc/markview.nvim-integrations.txt
+++ b/doc/markview.nvim-integrations.txt
@@ -113,6 +113,23 @@ You can use `markview.nvim` to prettify the LSP hover window.
You can see an example here {6}.
+--------------------------------------------------------------------------------
+đŠ Fancy comments *markview.nvim-integrations.nvim-fancy_comments*
+
+â  Attention
+â This will remap `gx` by default! Set preview.map_gx {7} to `false` to
+â overwrite this behavior.
+
+Conventional commit style commits can be rendered by `markview.nvim`.
+
+Demo {img:2}
+
+For this you would need a `comment` parser. You can use either,
+
+â stsewd/tree-sitter-comment {8}, which supports some simple syntax.
+â OXY2DEV/tree-sitter-comment {9}, which also supports a subset of `markdown` &
+ `vimdoc`. See [installation]().
+
Links ~
1: https://github.com/OXY2DEV/markview.nvim/wiki/Integrations
@@ -121,9 +138,13 @@ Links ~
4: `markview.nvim-markdown.headings`
5: `markview.nvim-markdown.list_items`
6: https://gist.github.com/OXY2DEV/645c90df32095a8a397735d0be646452
+7: `markview.nvim-preview.map_gx`
+8: https://github.com/stsewd/tree-sitter-comment
+9: https://github.com/OXY2DEV/tree-sitter-comment
Images ~
1: ./images/markview.nvim-lsp_hover.png
+2: ./images/comments/markview.nvim-comment.png
vim:ft=help:textwidth=80:tabstop=4:noexpandtab:
diff --git a/doc/markview.nvim-preview.txt b/doc/markview.nvim-preview.txt
index ddfe0ba..617bd93 100644
--- a/doc/markview.nvim-preview.txt
+++ b/doc/markview.nvim-preview.txt
@@ -23,7 +23,7 @@
---@field ignore_buftypes? string[] Buftypes that should be ignored(e.g. nofile).
---@field raw_previews? markview.config.preview.raw Options that will show up as raw in hybrid mode.
---
- ---@field condition? fun(buffer: integer): boolean Condition to check if a buffer should be attached or not.
+ ---@field condition? fun(buffer: integer): boolean? Condition to check if a buffer should be attached or not. Overrides `preview.filetypes` & `preview.ignore_buftypes`. If `nil` is returned, `preview.filetypes` & `preview.ignore_buftypes` are checked.
---
---@field modes? string[] Vim-modes where previews will be shown.
---@field hybrid_modes? string[] Vim-modes where `hybrid mode` is enabled. Options that should/shouldn't be previewed in `hybrid_modes`.
@@ -160,6 +160,7 @@ raw_previews *markview.nvim-preview.raw_previews*
--- in `hybrid mode`.
---@class markview.config.preview.raw
---
+ ---@field comment? markview.config.preview.raw.comment[]
---@field html? markview.config.preview.raw.html[]
---@field latex? markview.config.preview.raw.latex[]
---@field markdown? markview.config.preview.raw.markdown[]
@@ -196,11 +197,36 @@ condition *markview.nvim-preview.condition*
A function that returns a boolean indicating if a buffer should be attached to.
+â î Important
+â This will disable filetypes {9} & ignore_buftypes {8}.
+
â ó°œ Note
-â This is run after filetypes {9} & ignore_buftypes {8} is checked.
+â The function may return `nil`. In which case, filetypes {11} & ignore_buftypes
+â {10} will be checked.
Useful if you need sophisticated logic for buffer attaching.
+For example, this is the default value. It attaches to any buffer that has
+`tree-sitter` parser available when experimental.fancy_comments {12} is set to
+`true`.
+
+>lua
+ condition = function (buffer)
+ local is_enabled = spec.get({ "experimental", "fancy_comments" }, {
+ fallback = false,
+ });
+
+ if not is_enabled then
+ return false;
+ end
+
+ local success, parser = pcall(vim.treesitter.get_parser, buffer);
+ if success and parser ~= nil then
+ return true;
+ end
+ end,
+<
+
--------------------------------------------------------------------------------
modes *markview.nvim-preview.modes*
@@ -220,7 +246,7 @@ hybrid_modes *markview.nvim-preview.hybrid_modes*
Modes where `hybrid mode` will be shown.
â î Important
-â The mode must also be preset in modes {10} for this to take effect!
+â The mode must also be preset in modes {13} for this to take effect!
ââââââââââââââââââââââââŹâââââââââââââââââââââââź
â â `hybrid_modes = {}` â
@@ -238,7 +264,7 @@ linewise_hybrid_mode *markview.nvim-preview.linewise_hybrid_mode*
linewise_hybrid_mode = false,
<
-Enables `linewise` hybrid mode. edit_range {11} is used to control the number of
+Enables `linewise` hybrid mode. edit_range {14} is used to control the number of
lines to clear around each cursor.
ââââââââââââââââââââââââŹâââââââââââââââââââââââź
@@ -267,7 +293,7 @@ Maximum number of lines a buffer can have for it to be rendered completely.
â cause lag when opening the buffer.
If the line count is larger than this value, the buffer will be partially drawn.
-draw_range {12} is used to control the number of lines drawn around each cursor.
+draw_range {15} is used to control the number of lines drawn around each cursor.
--------------------------------------------------------------------------------
draw_range *markview.nvim-preview.draw_range*
@@ -291,10 +317,10 @@ edit_range *markview.nvim-preview.edit_range*
<
Number of lines above & below each cursor that are considered being edited. Only
-useful in hybrid_modes {13}.
+useful in hybrid_modes {16}.
â î Important
-â When linewise_hybrid_mode {14} is `false`, a Node only needs to partially be
+â When linewise_hybrid_mode {17} is `false`, a Node only needs to partially be
â within the range for it to be considered being edited.
â So, things such as List items, Block quotes etc. may clear more lines than the
â specified amount.
@@ -317,20 +343,23 @@ Window options for the `splitview` window. Passed directly to `nvim_open_win()`.
Links ~
-1: #-preview-options
-2: ./Experimental.md#prefer_nvim
-3: ./Experimental.md#file_open_command
-4: ./Experimental.md#prefer_nvim
-5: #ignore_buftypes
-6: #ignore_buftypes
-7: #hybrid_modes
-8: #ignore_buftypes
-9: #filetypes
-10: #modes
-11: #edit_range
-12: #draw_range
-13: #hybrid_modes
-14: #linewise_hybrid_mode
+1: `markview.nvim-preview`
+2: `markview.nvim-experimental.prefer_nvim`
+3: `markview.nvim-experimental.file_open_command`
+4: `markview.nvim-experimental.prefer_nvim`
+5: `markview.nvim-preview.ignore_buftypes`
+6: `markview.nvim-preview.ignore_buftypes`
+7: `markview.nvim-preview.modes`
+8: `markview.nvim-preview.ignore_buftypes`
+9: `markview.nvim-preview.filetypes`
+10: `markview.nvim-preview.ignore_buftypes`
+11: `markview.nvim-preview.filetypes`
+12: `markview.nvim-experimental.fancy_comments`
+13: `markview.nvim-preview.modes`
+14: `markview.nvim-preview.edit_range`
+15: `markview.nvim-preview.draw_range`
+16: `markview.nvim-preview.modes`
+17: `markview.nvim-preview.linewise_hybrid_mode`
Images ~
diff --git a/doc/markview.nvim.txt b/doc/markview.nvim.txt
index 4317ad2..cf7508e 100644
--- a/doc/markview.nvim.txt
+++ b/doc/markview.nvim.txt
@@ -8,7 +8,7 @@
â wrap {img:2} â nowrap {img:3} â
â°ââââââââââââââââââŽâââââââââââââââââââŻ
- Image {img:5} Image {img:4}
+ Image {img:6} Image {img:5} Image {img:4}
đ Wiki {3} | đ§© Extras {2} | đŠ Presets {1}
@@ -26,6 +26,7 @@ Core features,
â Highly customisable! You can change almost anything using the config!
â Dynamic `highlight groups` that automatically updates with the colorscheme!
â `Callout`, `checkbox` completions for `blink.cmp` & `nvim-cmp`.
+â Works with `tree-sitter injections` too!
--------------------------------------------------------------------------------
Table of contents
@@ -37,9 +38,37 @@ Table of contents
đ§© Extras ............................................... |markview.nvim-extras|
đŠ Presets ............................................. |markview.nvim-presets|
+Fancy comments, ~
+
+Image {img:7}
+
+â Comments are still experimental! The original parser only supports basic
+â features.
+
+Conventional commit style comments with support for a subset of `markdown` &
+`vimdoc`. See integrations#fancy-comments {6} For more info.
+
+Supported syntax,
+
+â Tasks(e.g. `feat`, `TODO` etc.)
+â Task scopes.
+
+Extra syntax(needs external parser),
+
+â `**Bold**`
+â `*Italic*`
+â `Code`
+â `'Quoted_text'`
+â `"Double quoted text"`
+â `@mentions`
+â `issues/reference#52`
+â `https://example.com`
+â `|help-section|`
+â Code blocks
+
HTML, ~
-Image {img:6}
+Image {img:8}
â Customizable previews for `container` & `void` elements.
â Supports the following container elements out of the box,
@@ -63,7 +92,7 @@ Image {img:6}
LaTeX, ~
-Image {img:7}
+Image {img:9}
â Supports basic LaTeX syntax,
â Math blocks(typically `$$...$$`) & inline math(typically `$...$`).
@@ -133,7 +162,7 @@ Image {img:7}
Markdown, ~
-Image {img:8}
+Image {img:10}
â Supports basic markdown(Github-flavored) syntax,
â Block quotes(with support for `callouts` & titles).
@@ -162,7 +191,7 @@ Image {img:8}
â `Org-mode` like indentation for headings.
-Image {img:9}
+Image {img:11}
â Obsidian/PKM extended syntax support,
â Block reference links.
@@ -178,7 +207,7 @@ Image {img:9}
Typst, ~
-Image {img:10}
+Image {img:12}
â Supports the following items,
â Code blocks.
@@ -206,7 +235,7 @@ Image {img:10}
YAML, ~
-Image {img:11}
+Image {img:13}
â Custom property icons.
â Custom property scope decorations.
@@ -229,8 +258,8 @@ Hybrid mode ~
ââââââââââââââââââââââââŹâââââââââââââââââââââââź
â Normal hybrid mode â Linewise hybrid mode â
ââââââââââââââââââââââââŒâââââââââââââââââââââââ€
-â hybrid_mode {img:12} â linewise_hybrid_mode â
-â â {img:13} â
+â hybrid_mode {img:14} â linewise_hybrid_mode â
+â â {img:15} â
â°âââââââââââââââââââââââŽâââââââââââââââââââââââŻ
â Node-based edit range(default).
@@ -254,7 +283,7 @@ Internal Icon provider features,
â 708 different filetype configuration.
â Dynamic highlight groups for matching the colorscheme.
-Image {img:14}
+Image {img:16}
â You can use `:Markview traceShow` to see what the plugin has been
doing(including how long some of them took).
@@ -290,8 +319,8 @@ External icon providers,
}
<
-â mini.icons {6}
-â nvim-web-devicons {7}
+â mini.icons {7}
+â nvim-web-devicons {8}
Parsers,
@@ -308,6 +337,7 @@ Parsers,
â `markdown`
â `markdown_inline`
+â `comment`(optional)
â `html`(optional)
â `latex`(optional)
â `typst`(optional)
@@ -340,7 +370,7 @@ Add this to your plugin list.
â cause more time for the previews to load when starting Neovim!
The plugin should be loaded after your colorscheme to ensure the correct
-highlight groups are used. See integrations.transparent_colorschemes {8} if you
+highlight groups are used. See integrations.transparent_colorschemes {9} if you
use a transparent colorscheme and the colors don't look right.
>lua
@@ -389,7 +419,7 @@ use a transparent colorscheme and the colors don't look right.
đ„ GitHub release ~
-Tagged releases can be found in the release page {9}.
+Tagged releases can be found in the release page {10}.
â ó°œ Note
â `Github releases` may sometimes be slightly behind `main`.
@@ -409,7 +439,7 @@ Tagged releases can be found in the release page {9}.
--------------------------------------------------------------------------------
đ§ Usage
-You can find more usage recipes here {10}.
+You can find more usage recipes here {11}.
--------------------------------------------------------------------------------
đ Commands *markview.nvim-commands*
@@ -553,27 +583,30 @@ Links ~
3: https://github.com/OXY2DEV/markview.nvim/wiki/Home
4: https://github.com/OXY2DEV/markview.nvim/wiki/Integrations#-nowrap
5: https://github.com/OXY2DEV/markview.nvim/wiki/Integrations#-wrap
-6: https://github.com/nvim-mini/mini.icons
-7: https://github.com/nvim-tree/nvim-web-devicons
-8: https://github.com/OXY2DEV/markview.nvim/wiki/Integrations#-transparent-colorschemes
-9: https://github.com/OXY2DEV/markview.nvim/releases
-10: |markview.nvim-usage|
+6: https://github.com/OXY2DEV/markview.nvim/wiki/Integrations#-fancy-comments
+7: https://github.com/nvim-mini/mini.icons
+8: https://github.com/nvim-tree/nvim-web-devicons
+9: https://github.com/OXY2DEV/markview.nvim/wiki/Integrations#-transparent-colorschemes
+10: https://github.com/OXY2DEV/markview.nvim/releases
+11: |markview.nvim-usage|
Images ~
1: https://github.com/OXY2DEV/markview.nvim/blob/images/v27/markview.nvim-splitview.png
2: https://github.com/OXY2DEV/markview.nvim/blob/images/v27/markview.nvim-wrap.png
3: https://github.com/OXY2DEV/markview.nvim/blob/images/v27/markview.nvim-nowrap.png
-4: https://github.com/OXY2DEV/markview.nvim/blob/images/v27/markview.nvim-hybrid_mode.png
-5: https://github.com/OXY2DEV/markview.nvim/blob/images/v27/markview.nvim-splitview_2.png
-6: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/repo/html-tokyonight_night.png
-7: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/repo/latex-cyberdream.png
-8: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/repo/markdown-catppuccin_mocha.png
-9: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/repo/markdown_inline-nightfly.png
-10: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/repo/typst-kanagawa_wave.png
-11: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/repo/yaml-material_palenight.png
-12: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/wiki/hybrid_mode.png
-13: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/wiki/linewise_hybrid_mode.png
-14: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/repo/traceback.png
+4: https://github.com/OXY2DEV/markview.nvim/blob/images/v27/markview.nvim-comment.png
+5: https://github.com/OXY2DEV/markview.nvim/blob/images/v27/markview.nvim-hybrid_mode.png
+6: https://github.com/OXY2DEV/markview.nvim/blob/images/v27/markview.nvim-splitview_2.png
+7: https://github.com/OXY2DEV/markview.nvim/wiki/images/comment/markview.nvim-comment.injection.png
+8: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/repo/html-tokyonight_night.png
+9: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/repo/latex-cyberdream.png
+10: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/repo/markdown-catppuccin_mocha.png
+11: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/repo/markdown_inline-nightfly.png
+12: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/repo/typst-kanagawa_wave.png
+13: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/repo/yaml-material_palenight.png
+14: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/wiki/hybrid_mode.png
+15: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/wiki/linewise_hybrid_mode.png
+16: https://github.com/OXY2DEV/markview.nvim/blob/images/v25/repo/traceback.png
vim:ft=help:textwidth=80:tabstop=4:noexpandtab:
diff --git a/doc/tags b/doc/tags
index fad81fd..959bcad 100644
--- a/doc/tags
+++ b/doc/tags
@@ -3,12 +3,24 @@ markview.nvim markview.nvim.txt /*markview.nvim*
markview.nvim-advanced markview.nvim-advanced.txt /*markview.nvim-advanced*
markview.nvim-autocmds markview.nvim-autocmds.txt /*markview.nvim-autocmds*
markview.nvim-commands markview.nvim.txt /*markview.nvim-commands*
+markview.nvim-comment markview.nvim-comment.txt /*markview.nvim-comment*
+markview.nvim-comment.autolinks markview.nvim-comment.txt /*markview.nvim-comment.autolinks*
+markview.nvim-comment.code_blocks markview.nvim-comment.txt /*markview.nvim-comment.code_blocks*
+markview.nvim-comment.enable markview.nvim-comment.txt /*markview.nvim-comment.enable*
+markview.nvim-comment.inline_codes markview.nvim-comment.txt /*markview.nvim-comment.inline_codes*
+markview.nvim-comment.issues markview.nvim-comment.txt /*markview.nvim-comment.issues*
+markview.nvim-comment.mentions markview.nvim-comment.txt /*markview.nvim-comment.mentions*
+markview.nvim-comment.taglinks markview.nvim-comment.txt /*markview.nvim-comment.taglinks*
+markview.nvim-comment.task_scopes markview.nvim-comment.txt /*markview.nvim-comment.task_scopes*
+markview.nvim-comment.tasks markview.nvim-comment.txt /*markview.nvim-comment.tasks*
+markview.nvim-comment.urls markview.nvim-comment.txt /*markview.nvim-comment.urls*
markview.nvim-config markview.nvim-config.txt /*markview.nvim-config*
markview.nvim-contribute markview.nvim.txt /*markview.nvim-contribute*
markview.nvim-dev.txt markview.nvim-dev.txt /*markview.nvim-dev.txt*
markview.nvim-experimental markview.nvim-experimental.txt /*markview.nvim-experimental*
markview.nvim-experimental.date_formats markview.nvim-experimental.txt /*markview.nvim-experimental.date_formats*
markview.nvim-experimental.date_time_formats markview.nvim-experimental.txt /*markview.nvim-experimental.date_time_formats*
+markview.nvim-experimental.fancy_comments markview.nvim-experimental.txt /*markview.nvim-experimental.fancy_comments*
markview.nvim-experimental.file_open_command markview.nvim-experimental.txt /*markview.nvim-experimental.file_open_command*
markview.nvim-experimental.linewise_ignore_org_indent markview.nvim-experimental.txt /*markview.nvim-experimental.linewise_ignore_org_indent*
markview.nvim-experimental.list_empty_line_tolerance markview.nvim-experimental.txt /*markview.nvim-experimental.list_empty_line_tolerance*
@@ -30,6 +42,7 @@ markview.nvim-integrations.blink-cmp markview.nvim-integrations.txt /*markview.n
markview.nvim-integrations.color_blending markview.nvim-integrations.txt /*markview.nvim-integrations.color_blending*
markview.nvim-integrations.gx markview.nvim-integrations.txt /*markview.nvim-integrations.gx*
markview.nvim-integrations.nowrap markview.nvim-integrations.txt /*markview.nvim-integrations.nowrap*
+markview.nvim-integrations.nvim-fancy_comments markview.nvim-integrations.txt /*markview.nvim-integrations.nvim-fancy_comments*
markview.nvim-integrations.transparent_colorschemes markview.nvim-integrations.txt /*markview.nvim-integrations.transparent_colorschemes*
markview.nvim-integrations.wrap markview.nvim-integrations.txt /*markview.nvim-integrations.wrap*
markview.nvim-latex markview.nvim-latex.txt /*markview.nvim-latex*
diff --git a/lua/markview/autocmds.lua b/lua/markview/autocmds.lua
index c5f5494..e709c9a 100644
--- a/lua/markview/autocmds.lua
+++ b/lua/markview/autocmds.lua
@@ -86,15 +86,27 @@ autocmds.should_detach = function (args)
local condition = spec.get({ "preview", "condition" }, { eval_args = { args.buf } });
- if vim.list_contains(ignore_bt, bt) == true then
- return true;
- elseif vim.list_contains(attach_ft, ft) == false then
- return true;
- elseif condition == false then
- return true;
+ --[[
+ feat: Attaching to buffers.
+
+ If condition is `true`(either `preview.condition = true` or the evaluated function value is `true`), attach to `buffer`.
+
+ Otherwise, check if the **buftype** is included in `preview.ignore_buftypes`. If it is then we don't attach to `buffer`.
+ Then check if the **filetype** is included in `preview.filetypes`. IF it is we attach to `buffer`.
+ ]]
+ if condition == nil then
+ -- No condition specified.
+
+ if vim.list_contains(ignore_bt, bt) == true then
+ --- Ignored buffer type.
+ return true;
+ elseif vim.list_contains(attach_ft, ft) == false then
+ --- Ignored file type.
+ return true;
+ end
end
- return false;
+ return condition == false;
---|fE
end
@@ -183,13 +195,26 @@ autocmds.bufHandle = function (args)
local condition = spec.get({ "preview", "condition" }, { eval_args = { args.buf }, ignore_enable = true });
- if vim.list_contains(ignore_bt, bt) == true then
- --- Ignored buffer type.
- return;
- elseif vim.list_contains(attach_ft, ft) == false then
- --- Ignored file type.
- return;
+ --[[
+ feat: Attaching to buffers.
+
+ If condition is `true`(either `preview.condition = true` or the evaluated function value is `true`), attach to `buffer`.
+
+ Otherwise, check if the **buftype** is included in `preview.ignore_buftypes`. If it is then we don't attach to `buffer`.
+ Then check if the **filetype** is included in `preview.filetypes`. IF it is we attach to `buffer`.
+ ]]
+ if condition == nil then
+ -- No condition specified.
+
+ if vim.list_contains(ignore_bt, bt) == true then
+ --- Ignored buffer type.
+ return;
+ elseif vim.list_contains(attach_ft, ft) == false then
+ --- Ignored file type.
+ return;
+ end
elseif condition == false then
+ -- Condition not met.
return;
end
diff --git a/lua/markview/config/comment.lua b/lua/markview/config/comment.lua
new file mode 100644
index 0000000..f24b666
--- /dev/null
+++ b/lua/markview/config/comment.lua
@@ -0,0 +1,904 @@
+local function normalize_str(str)
+ if type(str) ~= "string" then
+ return "";
+ end
+
+ return string.lower(str):gsub("^%l", string.upper);
+end
+
+
+---@type markview.config.comment
+return {
+ enable = true,
+
+ autolinks = {
+ enable = true,
+
+ default = {
+ icon = "ó°œ ",
+ hl = "MarkviewPalette6",
+ },
+
+ ---|fS
+
+ --NOTE(@OXY2DEV): Github sites.
+
+ ["github%.com/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com/
+ icon = "îȘ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return string.match(item.destination, "github%.com/([%a%d%-%_%.]+)%/?$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com//
+ icon = "ó°ł ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/?$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+/tree/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com///tree/
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ local repo, branch = string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)/tree/([%a%d%-%_%.]+)%/?$");
+ return repo .. " at " .. branch;
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+/commits/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com///commits/
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+/commits/[%a%d%-%_%.]+)%/?$");
+ end
+ },
+
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/releases$"] = {
+ --- github.com///releases
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Releases âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/releases$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/tags$"] = {
+ --- github.com///tags
+ icon = "ïŹ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Tags âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/tags$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/issues$"] = {
+ --- github.com///issues
+ icon = "îŹ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Issues âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/issues$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/pulls$"] = {
+ --- github.com///pulls
+ icon = "îŠ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Pull requests âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/pulls$");
+ end
+ },
+
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/wiki$"] = {
+ --- github.com///wiki
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Wiki âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/wiki$");
+ end
+ },
+
+ --- NOTE(@OXY2DEV): Commonly used sites by programmers.
+
+ ["developer%.mozilla%.org"] = {
+ priority = -9999,
+
+ icon = "ó° ",
+ hl = "MarkviewPalette5Fg"
+ },
+
+ ["w3schools%.com"] = {
+ priority = -9999,
+
+ icon = "î ",
+ hl = "MarkviewPalette4Fg"
+ },
+
+ ["stackoverflow%.com"] = {
+ priority = -9999,
+
+ icon = "ó° ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["reddit%.com"] = {
+ priority = -9999,
+
+ icon = "ïĄ ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["github%.com"] = {
+ priority = -9999,
+
+ icon = "îȘ ",
+ hl = "MarkviewPalette6Fg"
+ },
+
+ ["gitlab%.com"] = {
+ priority = -9999,
+
+ icon = "î« ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["dev%.to"] = {
+ priority = -9999,
+
+ icon = "ó±Ž ",
+ hl = "MarkviewPalette0Fg"
+ },
+
+ ["codepen%.io"] = {
+ priority = -9999,
+
+ icon = "ï ",
+ hl = "MarkviewPalette6Fg"
+ },
+
+ ["replit%.com"] = {
+ priority = -9999,
+
+ icon = "îą ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["jsfiddle%.net"] = {
+ priority = -9999,
+
+ icon = "ï ",
+ hl = "MarkviewPalette5Fg"
+ },
+
+ ["npmjs%.com"] = {
+ priority = -9999,
+
+ icon = "î ",
+ hl = "MarkviewPalette0Fg"
+ },
+
+ ["pypi%.org"] = {
+ priority = -9999,
+
+ icon = "ó°Š ",
+ hl = "MarkviewPalette0Fg"
+ },
+
+ ["mvnrepository%.com"] = {
+ priority = -9999,
+
+ icon = "îŽ ",
+ hl = "MarkviewPalette1Fg"
+ },
+
+ ["medium%.com"] = {
+ priority = -9999,
+
+ icon = "ïș ",
+ hl = "MarkviewPalette6Fg"
+ },
+
+ ["linkedin%.com"] = {
+ priority = -9999,
+
+ icon = "ó°» ",
+ hl = "MarkviewPalette5Fg"
+ },
+
+ ["news%.ycombinator%.com"] = {
+ priority = -9999,
+
+ icon = "ï ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["neovim%.io/doc/user/.*#%_?.*$"] = {
+ icon = "ïŻ ",
+ hl = "MarkviewPalette4Fg",
+
+ text = function (_, item)
+ local file, tag = string.match(item.destination, "neovim%.io/doc/user/(.*)#%_?(.*)$");
+ --- The actual website seems to show
+ --- _ in the site name so, we won't
+ --- be replacing `_`s with ` `s.
+ file = string.gsub(file, "%.html$", "");
+
+ return string.format("%s(%s) - Neovim docs", normalize_str(file), tag);
+ end
+ },
+ ["neovim%.io/doc/user/.*$"] = {
+ icon = "ïŻ ",
+ hl = "MarkviewPalette4Fg",
+
+ text = function (_, item)
+ local file = string.match(item.destination, "neovim%.io/doc/user/(.*)$");
+ file = string.gsub(file, "%.html$", "");
+
+ return string.format("%s - Neovim docs", normalize_str(file));
+ end
+ },
+
+ ["github%.com/vim/vim"] = {
+ priority = -100,
+
+ icon = "î
",
+ hl = "MarkviewPalette4Fg",
+ },
+
+ ["github%.com/neovim/neovim"] = {
+ priority = -100,
+
+ icon = "ïŻ ",
+ hl = "MarkviewPalette4Fg",
+ },
+
+ ["vim%.org"] = {
+ icon = "î
",
+ hl = "MarkviewPalette4Fg",
+ },
+
+ ["luals%.github%.io/wiki/?.*$"] = {
+ icon = "î ",
+ hl = "MarkviewPalette5Fg",
+
+ text = function (_, item)
+ if string.match(item.destination, "luals%.github%.io/wiki/(.-)/#(.+)$") then
+ local page_mappings = {
+ annotations = {
+ ["as"] = "@as",
+ ["alias"] = "@alias",
+ ["async"] = "@async",
+ ["cast"] = "@cast",
+ ["class"] = "@class",
+ ["deprecated"] = "@deprecated",
+ ["diagnostic"] = "@diagnostic",
+ ["enum"] = "@enum",
+ ["field"] = "@field",
+ ["generic"] = "@generic",
+ ["meta"] = "@meta",
+ ["module"] = "@module",
+ ["nodiscard"] = "@nodiscard",
+ ["operator"] = "@operator",
+ ["overload"] = "@overload",
+ ["package"] = "@package",
+ ["param"] = "@param",
+ ["see"] = "@see",
+ ["source"] = "@source",
+ ["type"] = "@type",
+ ["vaarg"] = "@vaarg",
+ ["version"] = "@version"
+ }
+ };
+
+ local page, section = string.match(item.destination, "luals%.github%.io/wiki/(.-)/#(.+)$");
+
+ if page_mappings[page] and page_mappings[page][section] then
+ section = page_mappings[page][section];
+ else
+ section = normalize_str(string.gsub(section, "%-", " "));
+ end
+
+ return string.format("%s(%s) | Lua Language Server", normalize_str(page), section);
+ elseif string.match(item.destination, "") then
+ local page = string.match(item.destination, "luals%.github%.io/wiki/(.-)/?$");
+
+ return string.format("%s | Lua Language Server", normalize_str(page));
+ else
+ return item.destination;
+ end
+ end
+ },
+
+ ---|fE
+ },
+
+ bolds = {
+ enable = true,
+ },
+
+ code_blocks = {
+ enable = true,
+
+ border_hl = "MarkviewCode",
+ info_hl = "MarkviewCodeInfo",
+
+ label_direction = "right",
+ label_hl = nil,
+
+ min_width = 60,
+ pad_amount = 2,
+ pad_char = " ",
+
+ default = {
+ block_hl = "MarkviewCode",
+ pad_hl = "MarkviewCode"
+ },
+
+ ["diff"] = {
+ block_hl = function (_, line)
+ if line:match("^%+") then
+ return "MarkviewPalette4";
+ elseif line:match("^%-") then
+ return "MarkviewPalette1";
+ else
+ return "MarkviewCode";
+ end
+ end,
+ pad_hl = "MarkviewCode"
+ },
+
+ style = "block",
+ sign = true,
+ },
+
+ inline_codes = {
+ padding_left = " ",
+ padding_right = " ",
+
+ hl = "MarkviewInlineCode",
+ },
+
+ issues = {
+ enable = true,
+
+ default = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "îŹ ",
+
+ hl = "MarkviewPalette2",
+ },
+ },
+
+ italics = {
+ enable = true,
+ },
+
+ mentions = {
+ enable = true,
+
+ default = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ï ",
+
+ hl = "MarkviewPalette5",
+ },
+ },
+
+ taglinks = {
+ enable = true,
+
+ default = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°· ",
+
+ hl = "MarkviewHyperlink",
+ },
+ },
+
+ tasks = {
+ enable = true,
+
+ default = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°° ",
+
+ hl = "MarkviewPalette1",
+ },
+
+ ["^feat"] = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó±
",
+
+ hl = "MarkviewPalette7",
+ },
+
+ praise = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó±„ ",
+
+ hl = "MarkviewPalette3",
+ },
+
+ ["^suggest"] = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°Ł ",
+
+ hl = "MarkviewPalette2",
+ },
+
+ thought = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°§ ",
+
+ hl = "MarkviewPalette0",
+ },
+
+ note = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó° ź ",
+
+ hl = "MarkviewPalette5",
+ },
+
+ ["^info"] = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°Œ ",
+
+ hl = "MarkviewPalette0",
+ },
+
+ xxx = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°œ ",
+
+ hl = "MarkviewPalette0",
+ },
+
+ ["^nit"] = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°©° ",
+
+ hl = "MarkviewPalette6",
+ },
+
+ ["^warn"] = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = " ",
+
+ hl = "MarkviewPalette3",
+ },
+
+ fix = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°š ",
+
+ hl = "MarkviewPalette7",
+ },
+
+ hack = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó± ",
+
+ hl = "MarkviewPalette1",
+ },
+
+ typo = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ïš ",
+
+ hl = "MarkviewPalette0",
+ },
+
+ wip = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°Š ",
+
+ hl = "MarkviewPalette2",
+ },
+
+ issue = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "îŹ ",
+
+ hl = "MarkviewPalette1",
+ },
+
+ ["error"] = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°
",
+
+ hl = "MarkviewPalette1",
+ },
+
+ fixme = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°¶Ż ",
+
+ hl = "MarkviewPalette4",
+ },
+
+ deprecated = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°© ",
+
+ hl = "MarkviewPalette1",
+ },
+ },
+
+ task_scopes = {
+ enable = true,
+
+ default = {
+ padding_left = " ",
+ padding_right = " ",
+
+ icon = "ó°Č ",
+
+ hl = "MarkviewPalette4",
+ },
+ },
+
+ urls = {
+ enable = true,
+
+ default = {
+ icon = "ó°· ",
+
+ hl = "MarkviewHyperlink",
+ },
+
+ ---|fS
+
+ --NOTE(@OXY2DEV): Github sites.
+
+ ["github%.com/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com/
+ icon = "îȘ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return string.match(item.destination, "github%.com/([%a%d%-%_%.]+)%/?$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com//
+ icon = "ó°ł ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/?$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+/tree/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com///tree/
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ local repo, branch = string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)/tree/([%a%d%-%_%.]+)%/?$");
+ return repo .. " at " .. branch;
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+/commits/[%a%d%-%_%.]+%/?$"] = {
+ --- github.com///commits/
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+/commits/[%a%d%-%_%.]+)%/?$");
+ end
+ },
+
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/releases$"] = {
+ --- github.com///releases
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Releases âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/releases$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/tags$"] = {
+ --- github.com///tags
+ icon = "ïŹ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Tags âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/tags$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/issues$"] = {
+ --- github.com///issues
+ icon = "îŹ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Issues âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/issues$");
+ end
+ },
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/pulls$"] = {
+ --- github.com///pulls
+ icon = "îŠ ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Pull requests âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/pulls$");
+ end
+ },
+
+ ["github%.com/[%a%d%-%_%.]+/[%a%d%-%_%.]+%/wiki$"] = {
+ --- github.com///wiki
+ icon = "ï ",
+ hl = "MarkviewPalette0Fg",
+
+ text = function (_, item)
+ return "Wiki âą " .. string.match(item.destination, "github%.com/([%a%d%-%_%.]+/[%a%d%-%_%.]+)%/wiki$");
+ end
+ },
+
+ --- NOTE(@OXY2DEV): Commonly used sites by programmers.
+
+ ["developer%.mozilla%.org"] = {
+ priority = -9999,
+
+ icon = "ó° ",
+ hl = "MarkviewPalette5Fg"
+ },
+
+ ["w3schools%.com"] = {
+ priority = -9999,
+
+ icon = "î ",
+ hl = "MarkviewPalette4Fg"
+ },
+
+ ["stackoverflow%.com"] = {
+ priority = -9999,
+
+ icon = "ó° ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["reddit%.com"] = {
+ priority = -9999,
+
+ icon = "ïĄ ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["github%.com"] = {
+ priority = -9999,
+
+ icon = "îȘ ",
+ hl = "MarkviewPalette6Fg"
+ },
+
+ ["gitlab%.com"] = {
+ priority = -9999,
+
+ icon = "î« ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["dev%.to"] = {
+ priority = -9999,
+
+ icon = "ó±Ž ",
+ hl = "MarkviewPalette0Fg"
+ },
+
+ ["codepen%.io"] = {
+ priority = -9999,
+
+ icon = "ï ",
+ hl = "MarkviewPalette6Fg"
+ },
+
+ ["replit%.com"] = {
+ priority = -9999,
+
+ icon = "îą ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["jsfiddle%.net"] = {
+ priority = -9999,
+
+ icon = "ï ",
+ hl = "MarkviewPalette5Fg"
+ },
+
+ ["npmjs%.com"] = {
+ priority = -9999,
+
+ icon = "î ",
+ hl = "MarkviewPalette0Fg"
+ },
+
+ ["pypi%.org"] = {
+ priority = -9999,
+
+ icon = "ó°Š ",
+ hl = "MarkviewPalette0Fg"
+ },
+
+ ["mvnrepository%.com"] = {
+ priority = -9999,
+
+ icon = "îŽ ",
+ hl = "MarkviewPalette1Fg"
+ },
+
+ ["medium%.com"] = {
+ priority = -9999,
+
+ icon = "ïș ",
+ hl = "MarkviewPalette6Fg"
+ },
+
+ ["linkedin%.com"] = {
+ priority = -9999,
+
+ icon = "ó°» ",
+ hl = "MarkviewPalette5Fg"
+ },
+
+ ["news%.ycombinator%.com"] = {
+ priority = -9999,
+
+ icon = "ï ",
+ hl = "MarkviewPalette2Fg"
+ },
+
+ ["neovim%.io/doc/user/.*#%_?.*$"] = {
+ icon = "ïŻ ",
+ hl = "MarkviewPalette4Fg",
+
+ text = function (_, item)
+ local file, tag = string.match(item.destination, "neovim%.io/doc/user/(.*)#%_?(.*)$");
+ --- The actual website seems to show
+ --- _ in the site name so, we won't
+ --- be replacing `_`s with ` `s.
+ file = string.gsub(file, "%.html$", "");
+
+ return string.format("%s(%s) - Neovim docs", normalize_str(file), tag);
+ end
+ },
+ ["neovim%.io/doc/user/.*$"] = {
+ icon = "ïŻ ",
+ hl = "MarkviewPalette4Fg",
+
+ text = function (_, item)
+ local file = string.match(item.destination, "neovim%.io/doc/user/(.*)$");
+ file = string.gsub(file, "%.html$", "");
+
+ return string.format("%s - Neovim docs", normalize_str(file));
+ end
+ },
+
+ ["github%.com/vim/vim"] = {
+ priority = -100,
+
+ icon = "î
",
+ hl = "MarkviewPalette4Fg",
+ },
+
+ ["github%.com/neovim/neovim"] = {
+ priority = -100,
+
+ icon = "ïŻ ",
+ hl = "MarkviewPalette4Fg",
+ },
+
+ ["vim%.org"] = {
+ icon = "î
",
+ hl = "MarkviewPalette4Fg",
+ },
+
+ ["luals%.github%.io/wiki/?.*$"] = {
+ icon = "î ",
+ hl = "MarkviewPalette5Fg",
+
+ text = function (_, item)
+ if string.match(item.destination, "luals%.github%.io/wiki/(.-)/#(.+)$") then
+ local page_mappings = {
+ annotations = {
+ ["as"] = "@as",
+ ["alias"] = "@alias",
+ ["async"] = "@async",
+ ["cast"] = "@cast",
+ ["class"] = "@class",
+ ["deprecated"] = "@deprecated",
+ ["diagnostic"] = "@diagnostic",
+ ["enum"] = "@enum",
+ ["field"] = "@field",
+ ["generic"] = "@generic",
+ ["meta"] = "@meta",
+ ["module"] = "@module",
+ ["nodiscard"] = "@nodiscard",
+ ["operator"] = "@operator",
+ ["overload"] = "@overload",
+ ["package"] = "@package",
+ ["param"] = "@param",
+ ["see"] = "@see",
+ ["source"] = "@source",
+ ["type"] = "@type",
+ ["vaarg"] = "@vaarg",
+ ["version"] = "@version"
+ }
+ };
+
+ local page, section = string.match(item.destination, "luals%.github%.io/wiki/(.-)/#(.+)$");
+
+ if page_mappings[page] and page_mappings[page][section] then
+ section = page_mappings[page][section];
+ else
+ section = normalize_str(string.gsub(section, "%-", " "));
+ end
+
+ return string.format("%s(%s) | Lua Language Server", normalize_str(page), section);
+ elseif string.match(item.destination, "") then
+ local page = string.match(item.destination, "luals%.github%.io/wiki/(.-)/?$");
+
+ return string.format("%s | Lua Language Server", normalize_str(page));
+ else
+ return item.destination;
+ end
+ end
+ },
+
+ ---|fE
+ },
+};
diff --git a/lua/markview/filetypes.lua b/lua/markview/filetypes.lua
index 34115c5..41e4baa 100644
--- a/lua/markview/filetypes.lua
+++ b/lua/markview/filetypes.lua
@@ -781,7 +781,7 @@ fts.get = function (ft)
end
local this_conf = fts.styles[_ft] or fts.styles[ft] or fts.styles.default;
- conf.name = this_conf.name or string.gsub(ft, "^%w", string.upper) or "Unknown";
+ conf.name = this_conf.name or ( type(ft) == "string" and string.gsub(ft, "^%w", string.upper) or "Unknown" );
return conf;
end
diff --git a/lua/markview/parser.lua b/lua/markview/parser.lua
index fa73912..aa7a82b 100644
--- a/lua/markview/parser.lua
+++ b/lua/markview/parser.lua
@@ -99,6 +99,7 @@ parser.init = function (buffer, from, to, cache)
---|fS
local _parsers = {
+ comment = require("markview.parsers.comment");
markdown = require("markview.parsers.markdown");
markdown_inline = require("markview.parsers.markdown_inline");
html = require("markview.parsers.html");
diff --git a/lua/markview/parsers/comment.lua b/lua/markview/parsers/comment.lua
new file mode 100644
index 0000000..053df4a
--- /dev/null
+++ b/lua/markview/parsers/comment.lua
@@ -0,0 +1,552 @@
+--- HTML parser for `markview.nvim`.
+local comment = {};
+
+--- Queried contents
+---@type table[]
+comment.content = {};
+
+--- Queried contents, but sorted
+---@type markview.parsed.comment_sorted
+---@diagnostic disable-next-line: missing-fields
+comment.sorted = {}
+
+--[[ Wrapper for `table.insert()`. ]]
+---@param data table
+comment.insert = function (data)
+ table.insert(comment.content, data);
+
+ if not comment.sorted[data.class] then
+ comment.sorted[data.class] = {};
+ end
+
+ table.insert(comment.sorted[data.class], data);
+end
+
+--[[
+Conventional commit style tasks.
+
+```comment
+feat: Added comment parser.
+```
+]]
+---@param buffer integer
+---@param TSNode TSNode
+---@param text string[]
+---@param range markview.parsed.comment.tasks.range
+comment.task = function (buffer, TSNode, text, range)
+ ---|fS
+
+ local kind = TSNode:field("type")[1];
+
+ for child in TSNode:iter_children() do
+ if child:type() == ":" then
+ _, _, range.label_row_end, range.label_col_end = child:range();
+ end
+ end
+
+ if not kind then
+ return;
+ end
+
+ range.kind = { kind:range(); };
+
+ comment.insert({
+ class = "comment_task",
+ kind = vim.treesitter.get_node_text(kind, buffer, {}),
+
+ text = text,
+ range = range,
+ });
+
+ ---|fE
+end
+
+--[[
+Conventional commit style tasks(for the original parser).
+
+```comment
+feat: Added comment parser.
+```
+]]
+---@param buffer integer
+---@param TSNode TSNode
+---@param text string[]
+---@param range markview.parsed.comment.tasks.range
+comment.tag = function (buffer, TSNode, text, range)
+ ---|fS
+
+ local kind;
+
+ for child in TSNode:iter_children() do
+ if child:type() == "name" then
+ kind = child;
+ range.kind = { child:range() };
+
+ range.label_row_end = range.row_start;
+ range.label_col_end = range.kind[4] + 1; -- `:` is part of the label!
+ elseif child:type() == "user" then
+ local user_range = { child:range() };
+
+ range.label_row_end = range.row_start;
+ range.label_col_end = user_range[4] + 2; -- `:` is part of the label!
+
+ -- Add special syntax support for scope text.
+ comment.tag_scope(buffer, child, { vim.treesitter.get_node_text(child, buffer, {}) }, user_range);
+ end
+ end
+
+ if not kind then
+ return;
+ end
+
+ comment.insert({
+ class = "comment_task",
+ kind = vim.treesitter.get_node_text(kind, buffer, {}),
+
+ text = text,
+ range = range,
+ });
+
+ ---|fE
+end
+
+--[[
+Conventional commit style task scope(for the original parser).
+
+```comment
+feat(scope): Added comment parser.
+```
+]]
+---@param buffer integer
+---@param _ TSNode
+---@param text string[]
+---@param root_range markview.parsed.comment.tasks.range
+comment.tag_scope = function (buffer, _, text, root_range)
+ ---|fS
+
+ local lpeg = vim.lpeg;
+
+ local function as_wspace (m) return { kind = "space", value = m }; end
+ local function as_comma (m) return { kind = "comma", value = m }; end
+
+ local function as_issue (m) return { kind = "issue", value = m }; end
+ local function as_mention (m) return { kind = "mention", value = m }; end
+ local function as_word (m) return { kind = "word", value = m }; end
+
+ local space = lpeg.C( lpeg.S(" \t\n\r") ) / as_wspace;
+ local comma = lpeg.C( lpeg.P(",") ) / as_comma;
+
+ local walnum = lpeg.R("az", "AZ", "09");
+ local non_wspacse = 1 - ( space + comma );
+ local word = lpeg.C( walnum * (non_wspacse^0) ) / as_word;
+
+ local mention = lpeg.C( lpeg.P("@") * (non_wspacse^1) ) / as_mention;
+
+ local num_issue = lpeg.C( lpeg.P("#") * ( lpeg.R("09") ^ 1 ) ) / as_issue;
+
+ local invalid_cahrs = space + lpeg.P("#");
+ local issue_name = lpeg.R("az", "AZ", "09") * (1 - invalid_cahrs)^0;
+ local desc_issue = lpeg.C( issue_name * lpeg.P("#") * ( lpeg.R("09") ^ 1 ) ) / as_issue;
+
+ local token = space + comma + desc_issue + num_issue + mention + word;
+
+ --[[
+ A scope may contain one or more `token`s separated by `,` & *whitespaces*.
+
+ Valid tokens may be any of,
+
+ - Mentions(`@foo`).
+ - Issue reference(`#48`, `OXY2DEV/markview.nvim#48`).
+ - Keyword(must start with a letter).
+ ]]
+ local scope = lpeg.Ct(token^0);
+
+ local col_start = root_range[2];
+
+ for _, item in ipairs(lpeg.match(scope, text[1] or "")) do
+ if item.kind == "word" then
+ comment.task_scope(buffer, nil, { item.value }, {
+ row_start = root_range[1],
+ col_start = col_start,
+
+ row_end = root_range[3],
+ col_end = col_start + #item.value,
+ });
+ elseif item.kind == "issue" then
+ comment.issue(buffer, nil, { item.value }, {
+ row_start = root_range[1],
+ col_start = col_start,
+
+ row_end = root_range[3],
+ col_end = col_start + #item.value,
+ });
+ elseif item.kind == "mention" then
+ comment.mention(buffer, nil, { item.value }, {
+ row_start = root_range[1],
+ col_start = col_start,
+
+ row_end = root_range[3],
+ col_end = col_start + #item.value,
+ });
+ end
+
+ col_start = col_start + #item.value;
+ end
+
+ ---|fE
+end
+
+--[[
+Conventional commit style task scope.
+
+```comment
+feat(scope): Added comment parser.
+```
+]]
+---@param text string[]
+---@param range markview.parsed.range
+comment.task_scope = function (_, _, text, range)
+ ---|fS
+
+ comment.insert({
+ class = "comment_task_scope",
+
+ text = text,
+ range = range,
+ });
+
+ ---|fE
+end
+
+---@param text string[]
+---@param range markview.parsed.range
+comment.bold = function (_, _, text, range)
+ ---|fS
+
+ comment.insert({
+ class = "comment_bold",
+
+ text = text,
+ range = range,
+ });
+
+ ---|fE
+end
+
+---@param text string[]
+---@param range markview.parsed.range
+comment.italic = function (_, _, text, range)
+ ---|fS
+
+ comment.insert({
+ class = "comment_italic",
+
+ text = text,
+ range = range,
+ });
+
+ ---|fE
+end
+
+---@param text string[]
+---@param range markview.parsed.range
+comment.inline_code = function (_, _, text, range)
+ comment.insert({
+ class = "comment_inline_code",
+
+ text = text,
+ range = range,
+ });
+end
+
+--[[
+Markdown-style fenced code blocks.
+
+```lua
+vim.print("Hello, Neovim!");
+```
+]]
+---@param buffer integer
+---@param TSNode TSNode
+---@param text string[]
+---@param range markview.parsed.comment.code_blocks.range
+comment.code_block = function (buffer, TSNode, text, range)
+ ---|fS
+
+ local uses_tab = false;
+
+ local lang = TSNode:field("language")[1];
+ local language;
+
+ if lang then
+ language = vim.treesitter.get_node_text(lang, buffer, {});
+ range.language = { lang:range() };
+ end
+
+ for _, line in ipairs(text) do
+ if string.match(line, "\t") then
+ uses_tab = true;
+ break;
+ end
+ end
+
+ ---@type TSNode, TSNode?
+ local start_delim, end_delim;
+
+ for child in TSNode:iter_children() do
+ if child:type() == "start_delimiter" then
+ start_delim = child;
+ local delim = vim.treesitter.get_node_text(child, buffer, {});
+
+ range.start_delim = { child:range() };
+ range.start_delim[2] = range.start_delim[2] + #string.match(delim, "^%s*");
+ elseif child:type() == "end_delimiter" then
+ end_delim = child;
+ local delim = vim.treesitter.get_node_text(child, buffer, {});
+
+ range.end_delim = { child:range() };
+ range.end_delim[2] = range.end_delim[2] + #string.match(delim, "^%s*");
+ end
+ end
+
+ comment.insert({
+ class = "comment_code_block",
+ uses_tab = uses_tab,
+
+ language = language,
+ info_string = nil,
+ delimiters = {
+ start_delim and vim.treesitter.get_node_text(start_delim, buffer) or "",
+ end_delim and vim.treesitter.get_node_text(end_delim, buffer) or "",
+ },
+
+ text = text,
+ range = range,
+ });
+
+ ---|fE
+end
+
+--[[
+Issue reference.
+
+It may be of any of the following format(s),
+
+- Numeric(`#99`).
+- Descriptive(`owner/repo#99`).
+
+```comment
+OXY2DEV/markview.nvim#48
+#48
+```
+]]
+---@param text string[]
+---@param range markview.parsed.range
+comment.issue = function (_, _, text, range)
+ ---|fS
+
+ comment.insert({
+ class = "comment_issue",
+
+ text = text,
+ range = range,
+ });
+
+ ---|fE
+end
+
+--[[
+User handle mention.
+
+```comment
+See, @username
+```
+]]
+---@param text string[]
+---@param range markview.parsed.range
+comment.mention = function (_, _, text, range)
+ ---|fS
+
+ comment.insert({
+ class = "comment_mention",
+
+ text = text,
+ range = range,
+ });
+
+ ---|fE
+end
+
+--[[
+URL.
+
+```comment
+www.example.com
+```
+]]
+---@param text string[]
+---@param range markview.parsed.range
+comment.url = function (_, _, text, range)
+ ---|fS
+
+ comment.insert({
+ class = "comment_url",
+ destination = text[1] or "",
+
+ text = text,
+ range = range,
+ });
+
+ ---|fE
+end
+
+--[[
+Markdown-like autolinks.
+
+```comment
+Mail to
+```
+]]
+---@param text string[]
+---@param range markview.parsed.range
+comment.autolink = function (_, _, text, range)
+ ---|fS
+
+ comment.insert({
+ class = "comment_autolink",
+ destination = string.gsub(text[1] or "", "^%<", ""):gsub("%>$", ""),
+
+ text = text,
+ range = range,
+ });
+
+ ---|fE
+end
+
+--[[
+Vimdoc-like help tag links.
+
+```comment
+See |intro.txt|
+```
+]]
+---@param text string[]
+---@param range markview.parsed.range
+comment.taglink = function (_, _, text, range)
+ ---|fS
+
+ comment.insert({
+ class = "comment_taglink",
+
+ text = text,
+ range = range,
+ });
+
+ ---|fE
+end
+
+---@param buffer integer
+---@param TSTree table
+---@param from integer?
+---@param to integer?
+---@return markview.parsed.comment[]
+---@return markview.parsed.comment_sorted
+comment.parse = function (buffer, TSTree, from, to)
+ ---|fS
+
+ ---@diagnostic disable-next-line: missing-fields
+ comment.sorted = {};
+ comment.content = {};
+
+ local scanned_queries;
+
+ if pcall(vim.treesitter.query.parse, "comment", "(source) @test") then
+ scanned_queries = vim.treesitter.query.parse("comment", [[
+ (tag) @comment.tag ; Task.
+ (uri) @comment.url
+ ]]);
+ else
+ scanned_queries = vim.treesitter.query.parse("comment", [[
+ (task) @comment.task
+
+ (task_scope
+ (word) @comment.task_scope)
+
+ (bold) @comment.bold
+ (italic) @comment.italic
+
+ (code) @comment.inline_code
+ (code_block) @comment.code_block
+
+ (issue_reference) @comment.issue
+ (mention) @comment.mention
+ (url) @comment.url
+ (autolink) @comment.autolink
+ (taglink) @comment.taglink
+ ]]);
+ end
+
+ for capture_id, capture_node, _, _ in scanned_queries:iter_captures(TSTree:root(), buffer, from, to) do
+ local capture_name = scanned_queries.captures[capture_id];
+
+ if not capture_name:match("^comment%.") then
+ goto continue;
+ end
+
+ ---@type string?
+ local capture_text = vim.treesitter.get_node_text(capture_node, buffer);
+ local r_start, c_start, r_end, c_end = capture_node:range();
+
+ if capture_text == nil then
+ goto continue;
+ end
+
+ if not capture_text:match("\n$") then
+ capture_text = capture_text .. "\n";
+ end
+
+ local lines = {};
+
+ for line in capture_text:gmatch("(.-)\n") do
+ table.insert(lines, line);
+ end
+
+ ---@type boolean, string
+ local success, error = pcall(
+ comment[capture_name:gsub("^comment%.", "")],
+
+ buffer,
+ capture_node,
+ lines,
+ {
+ row_start = r_start,
+ col_start = c_start,
+
+ row_end = r_end,
+ col_end = c_end
+ }
+ );
+
+ if success == false then
+ require("markview.health").print({
+ kind = "ERR",
+
+ from = "parsers/comment.lua",
+ fn = "parse()",
+
+ message = {
+ { tostring(error), "DiagnosticError" }
+ }
+ });
+ end
+
+ ::continue::
+ end
+
+ return comment.content, comment.sorted;
+
+ ---|fE
+end
+
+return comment;
+
diff --git a/lua/markview/renderer.lua b/lua/markview/renderer.lua
index 41fbcc9..3beaf54 100644
--- a/lua/markview/renderer.lua
+++ b/lua/markview/renderer.lua
@@ -15,6 +15,17 @@ renderer.__filter_cache = {
renderer.option_maps = {
---|fS
+ comment = {
+ autolinks = { "comment_autolink" },
+ code_blocks = { "comment_code_block" },
+ inline_codes = { "comment_inline_code" },
+ issues = { "comment_issue" },
+ mentions = { "comment_mention" },
+ taglinks = { "comment_taglink" },
+ task_scopes = { "comment_task_scope" },
+ tasks = { "comment_task" },
+ urls = { "comment_url" },
+ },
html = {
container_elements = { "html_container_element" },
headings = { "html_heading" },
@@ -34,31 +45,30 @@ renderer.option_maps = {
},
markdown = {
block_quotes = { "markdown_block_quote" },
+ checkboxes = { "markdown_checkbox" },
code_blocks = { "markdown_code_block" },
headings = { "markdown_atx_heading", "markdown_setext_heading" },
horizontal_rules = { "markdown_hr" },
list_items = { "markdown_list_item" },
metadata_minus = { "markdown_metadata_minus" },
metadata_plus = { "markdown_metadata_plus" },
- tables = { "markdown_table" },
reference_definitions = { "markdown_link_ref_definition" },
-
- checkboxes = { "markdown_checkbox" },
+ tables = { "markdown_table" },
},
markdown_inline = {
+ block_references = { "inline_link_block_ref" },
checkboxes = { "inline_checkbox" },
- inline_codes = { "inline_code_span" },
+ emails = { "inline_link_email" },
+ embed_files = { "inline_embed_files" },
entities = { "inline_entity" },
escapes = { "inline_escaped" },
footnotes = { "inline_footnote" },
highlights = { "inline_highlight" },
- block_references = { "inline_link_block_ref" },
- embed_files = { "inline_embed_files" },
- emails = { "inline_link_email" },
hyperlinks = { "inline_link_hyperlink", "inline_link_shortcut" },
images = { "inline_link_image" },
- uri_autolinks = { "inline_link_uri_autolink" },
+ inline_codes = { "inline_code_span" },
internal_links = { "inline_link_internal" },
+ uri_autolinks = { "inline_link_uri_autolink" },
},
typst = {
code_blocks = { "typst_code_block" },
@@ -67,16 +77,16 @@ renderer.option_maps = {
headings = { "typst_heading" },
labels = { "typst_label" },
list_items = { "typst_list_item" },
- reference_links = { "typst_link_ref" },
- url_links = { "typst_link_url" },
math_blocks = { "typst_math_blocks" },
math_spans = { "typst_math_spans" },
raw_blocks = { "typst_raw_block" },
raw_spans = { "typst_raw_span" },
+ reference_links = { "typst_link_ref" },
subscripts = { "typst_subscript" },
superscripts = { "typst_superscript" },
symbols = { "typst_symbol" },
terms = { "typst_terms" },
+ url_links = { "typst_link_url" },
},
yaml = {
properties = { "yaml_property" },
@@ -356,6 +366,7 @@ renderer.render = function (buffer, parsed_content)
---|fS
local _renderers = {
+ comment = require("markview.renderers.comment"),
html = require("markview.renderers.html"),
markdown = require("markview.renderers.markdown"),
markdown_inline = require("markview.renderers.markdown_inline"),
@@ -459,6 +470,7 @@ renderer.clear = function (buffer, from, to, hybrid_mode)
---|fS
local _renderers = {
+ comment = require("markview.renderers.comment");
html = require("markview.renderers.html");
markdown = require("markview.renderers.markdown");
markdown_inline = require("markview.renderers.markdown_inline");
diff --git a/lua/markview/renderers/comment.lua b/lua/markview/renderers/comment.lua
new file mode 100644
index 0000000..1774275
--- /dev/null
+++ b/lua/markview/renderers/comment.lua
@@ -0,0 +1,986 @@
+local comment = {};
+
+local utils = require("markview.utils");
+local spec = require("markview.spec");
+
+comment.ns = vim.api.nvim_create_namespace("markview/comment");
+
+---@param buffer integer
+---@param item markview.parsed.comment.autolinks
+comment.autolink = function (buffer, item)
+ ---|fS
+
+ ---@type markview.config.comment.autolinks?
+ local main_config = spec.get({ "comment", "autolinks" }, { fallback = nil });
+
+ if not main_config then
+ return;
+ end
+
+ ---@type markview.config.comments.autolinks.opts?
+ local config = utils.match(main_config, item.destination or "", {
+ ignore_keys = { "enable" },
+ eval_args = { buffer, item }
+ });
+
+ if not config then
+ return;
+ end
+
+ local range = item.range;
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_col = config.text and range.col_end - 1 or range.col_start + 1,
+ conceal = "",
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.corner_left or "", utils.set_hl(config.corner_left_hl or config.hl) },
+ { config.padding_left or "", utils.set_hl(config.padding_left_hl or config.hl) },
+
+ { config.icon or "", utils.set_hl(config.icon_hl or config.hl) },
+ config.text and { config.text, utils.set_hl(config.text_hl or config.hl) } or nil,
+ },
+
+ hl_mode = "combine"
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_row = range.row_end,
+ end_col = range.col_end,
+
+ hl_group = utils.set_hl(config.hl)
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_end, range.col_end - 1, {
+ undo_restore = false, invalidate = true,
+ end_col = range.col_end,
+ conceal = "",
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.padding_right or "", utils.set_hl(config.padding_right_hl or config.hl) },
+ { config.corner_right or "", utils.set_hl(config.corner_right_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ ---|fE
+end
+
+---@param buffer integer
+---@param item markview.parsed.comment.tasks
+comment.task = function (buffer, item)
+ ---|fS
+
+ ---@type markview.config.comment.tasks?
+ local main_config = spec.get({ "comment", "tasks" }, { fallback = nil });
+
+ if not main_config then
+ return;
+ end
+
+ ---@type markview.config.comment.tasks.opts?
+ local config = utils.match(main_config, item.kind, {
+ case_insensitive = true,
+
+ ignore_keys = { "enable" },
+ eval_args = { buffer, item }
+ });
+
+ if not config then
+ return;
+ end
+
+ local range = item.range;
+ local row_end = range.label_row_end or range.kind[3];
+ local col_end = range.label_col_end or range.kind[4];
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.corner_left or "", utils.set_hl(config.corner_left_hl or config.hl) },
+ { config.padding_left or "", utils.set_hl(config.padding_left_hl or config.hl) },
+
+ { config.icon or "", utils.set_hl(config.icon_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.kind[1], range.kind[2], {
+ undo_restore = false, invalidate = true,
+ end_row = row_end,
+ end_col = col_end,
+
+ hl_group = utils.set_hl(config.hl)
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, row_end, col_end - 1, {
+ undo_restore = false, invalidate = true,
+ end_col = col_end,
+ conceal = "",
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.padding_right or "", utils.set_hl(config.padding_right_hl or config.hl) },
+ { config.corner_right or "", utils.set_hl(config.corner_right_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ if config.desc_hl then
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, row_end, col_end, {
+ undo_restore = false, invalidate = true,
+ end_row = range.row_end,
+ end_col = range.col_end,
+
+ hl_group = utils.set_hl(config.desc_hl)
+ });
+ end
+
+ ---|fE
+end
+
+---@param buffer integer
+---@param item markview.parsed.comment.task_scopes
+comment.task_scope = function (buffer, item)
+ ---|fS
+
+ ---@type markview.config.comment.task_scopes?
+ local main_config = spec.get({ "comment", "task_scopes" }, { fallback = nil });
+
+ if not main_config then
+ return;
+ end
+
+ ---@type markview.config.__inline?
+ local config = utils.match(main_config, item.text[1] or "", {
+ ignore_keys = { "enable" },
+ eval_args = { buffer, item }
+ });
+
+ if not config then
+ return;
+ end
+
+ local range = item.range;
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.corner_left or "", utils.set_hl(config.corner_left_hl or config.hl) },
+ { config.padding_left or "", utils.set_hl(config.padding_left_hl or config.hl) },
+
+ { config.icon or "", utils.set_hl(config.icon_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_row = range.row_end,
+ end_col = range.col_end,
+
+ hl_group = utils.set_hl(config.hl)
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_end, range.col_end, {
+ undo_restore = false, invalidate = true,
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.padding_right or "", utils.set_hl(config.padding_right_hl or config.hl) },
+ { config.corner_right or "", utils.set_hl(config.corner_right_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ ---|fE
+end
+
+---@param buffer integer
+---@param item markview.parsed.comment.issues
+comment.issue = function (buffer, item)
+ ---|fS
+
+ ---@type markview.config.comment.tasks?
+ local main_config = spec.get({ "comment", "issues" }, { fallback = nil });
+
+ if not main_config then
+ return;
+ end
+
+ ---@type markview.config.comment.tasks.opts?
+ local config = utils.match(main_config, item.text[1] or "", {
+ ignore_keys = { "enable" },
+ eval_args = { buffer, item }
+ });
+
+ if not config then
+ return;
+ end
+
+ local range = item.range;
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.corner_left or "", utils.set_hl(config.corner_left_hl or config.hl) },
+ { config.padding_left or "", utils.set_hl(config.padding_left_hl or config.hl) },
+
+ { config.icon or "", utils.set_hl(config.icon_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_row = range.row_end,
+ end_col = range.col_end,
+
+ hl_group = utils.set_hl(config.hl)
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_end, range.col_end, {
+ undo_restore = false, invalidate = true,
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.padding_right or "", utils.set_hl(config.padding_right_hl or config.hl) },
+ { config.corner_right or "", utils.set_hl(config.corner_right_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ ---|fE
+end
+
+---@param buffer integer
+---@param item markview.parsed.comment.mentions
+comment.mention = function (buffer, item)
+ ---|fS
+
+ ---@type markview.config.comment.tasks?
+ local main_config = spec.get({ "comment", "mentions" }, { fallback = nil });
+
+ if not main_config then
+ return;
+ end
+
+ ---@type markview.config.comment.tasks.opts?
+ local config = utils.match(main_config, item.text[1] or "", {
+ ignore_keys = { "enable" },
+ eval_args = { buffer, item }
+ });
+
+ if not config then
+ return;
+ end
+
+ local range = item.range;
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_col = range.col_start + 1,
+ conceal = "",
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.corner_left or "", utils.set_hl(config.corner_left_hl or config.hl) },
+ { config.padding_left or "", utils.set_hl(config.padding_left_hl or config.hl) },
+
+ { config.icon or "", utils.set_hl(config.icon_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_row = range.row_end,
+ end_col = range.col_end,
+
+ hl_group = utils.set_hl(config.hl)
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_end, range.col_end, {
+ undo_restore = false, invalidate = true,
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.padding_right or "", utils.set_hl(config.padding_right_hl or config.hl) },
+ { config.corner_right or "", utils.set_hl(config.corner_right_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ ---|fE
+end
+
+---@param buffer integer
+---@param item markview.parsed.comment.inline_codes
+comment.inline_code = function (buffer, item)
+ ---|fS
+
+ ---@type markview.config.comment.inline_codes?
+ local config = spec.get({ "comment", "inline_codes" }, { fallback = nil });
+
+ if not config then
+ return;
+ end
+
+ local range = item.range;
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_col = range.col_start + 1,
+ conceal = "",
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.corner_left or "", utils.set_hl(config.corner_left_hl or config.hl) },
+ { config.padding_left or "", utils.set_hl(config.padding_left_hl or config.hl) },
+
+ { config.icon or "", utils.set_hl(config.icon_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_row = range.row_end,
+ end_col = range.col_end,
+
+ hl_group = utils.set_hl(config.hl)
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_end, range.col_end - 1, {
+ undo_restore = false, invalidate = true,
+ end_col = range.col_end,
+ conceal = "",
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.padding_right or "", utils.set_hl(config.padding_right_hl or config.hl) },
+ { config.corner_right or "", utils.set_hl(config.corner_right_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ ---|fE
+end
+
+--- Renders fenced code blocks.
+---@param buffer integer
+---@param item markview.parsed.comment.code_blocks
+comment.code_block = function (buffer, item)
+ ---|fS
+
+ ---@type markview.config.comment.code_blocks?
+ local config = spec.get({ "comment", "code_blocks" }, { fallback = nil, eval_args = { buffer, item } });
+
+ local delims = item.delimiters;
+ local range = item.range;
+
+ if not config then
+ return;
+ end
+
+ local decorations = require("markview.filetypes").get(item.language);
+ local label = { string.format(" %s%s ", decorations.icon, decorations.name), config.label_hl or decorations.icon_hl };
+ local win = utils.buf_getwin(buffer);
+
+ --- Gets highlight configuration for a line.
+ ---@param line string
+ ---@return markview.config.comment.code_blocks.opts
+ local function get_line_config(line)
+ local line_conf = utils.match(config, item.language, {
+ eval_args = { buffer, line },
+ def_fallback = {
+ block_hl = config.border_hl,
+ pad_hl = config.border_hl
+ },
+ fallback = {
+ block_hl = config.border_hl,
+ pad_hl = config.border_hl
+ }
+ });
+
+ return line_conf;
+ end
+
+ --[[ *Basic* rendering of `code blocks`. ]]
+ local function render_simple()
+ ---|fS
+
+ ---@cast config markview.config.comment.code_blocks.simple
+
+ local conceal_from = range.start_delim[2];
+ local conceal_to = range.col_start + #(item.text[1] or "");
+
+ if config.label_direction == nil or config.label_direction == "left" then
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, conceal_from, {
+ undo_restore = false, invalidate = true,
+
+ end_col = conceal_to,
+ conceal = "",
+
+ sign_text = config.sign == true and decorations.sign or nil,
+ sign_hl_group = utils.set_hl(config.sign_hl or decorations.sign_hl),
+
+ virt_text_pos = "inline",
+ virt_text = { label },
+
+ line_hl_group = utils.set_hl(config.border_hl)
+ });
+ else
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, conceal_from, {
+ undo_restore = false, invalidate = true,
+
+ end_col = conceal_to,
+ conceal = "",
+
+ sign_text = config.sign == true and decorations.sign or nil,
+ sign_hl_group = utils.set_hl(config.sign_hl or decorations.sign_hl),
+
+ virt_text_pos = "right_align",
+ virt_text = { label },
+
+ line_hl_group = utils.set_hl(config.border_hl)
+ });
+ end
+
+ --- Background
+ for l = range.row_start + 1, range.row_end - 1 do
+ local line = item.text[(l - range.row_start) + 1];
+ local line_config = get_line_config(line);
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, l, 0, {
+ undo_restore = false, invalidate = true,
+ end_row = l,
+
+ line_hl_group = utils.set_hl(line_config.block_hl --[[ @as string ]])
+ });
+ end
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_end, (range.col_start + #item.text[#item.text]) - #delims[2], {
+ undo_restore = false, invalidate = true,
+ end_col = range.col_start + #item.text[#item.text],
+ conceal = "",
+
+ line_hl_group = utils.set_hl(config.border_hl)
+ });
+
+ ---|fE
+ end
+
+ --- Renders block style code blocks.
+ local function render_block ()
+ ---|fS
+
+ ---@cast config markview.config.comment.code_blocks.block
+
+ ---|fS "chunk: Calculate various widths"
+
+ local pad_amount = config.pad_amount or 0;
+ local block_width = config.min_width or 60;
+
+ local pad_char = config.pad_char or " ";
+
+ ---@type integer[] Visual width of lines.
+ local line_widths = {};
+
+ for l, line in ipairs(item.text) do
+ local final = require("markview.renderers.markdown").get_visual_text:init(decorations.name, line);
+
+ if l ~= 1 and l ~= #item.text then
+ table.insert(line_widths, vim.fn.strdisplaywidth(final));
+
+ if vim.fn.strdisplaywidth(final) > (block_width - (2 * pad_amount)) then
+ block_width = vim.fn.strdisplaywidth(final) + (2 * pad_amount);
+ end
+ end
+ end
+
+ local label_width = utils.virt_len({ label });
+
+ ---|fE
+
+ local delim_conceal_from = range.start_delim[2];
+ local conceal_to = range.col_start + #(item.text[1] or "");
+
+ ---|fS "chunk: Top border"
+
+ local left_padding = pad_amount;
+
+ local pad_width = vim.fn.strdisplaywidth(
+ string.rep(pad_char, left_padding)
+ );
+
+ -- Hide the leading `backticks`s.
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+
+ end_col = conceal_to,
+ conceal = ""
+ });
+
+ if config.label_direction == "right" then
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, delim_conceal_from, {
+ virt_text_pos = "inline",
+ virt_text = {
+ {
+ string.rep(" " or pad_char, left_padding),
+ utils.set_hl(config.border_hl)
+ }
+ }
+ });
+ else
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start + #item.text[1], {
+ virt_text_pos = "inline",
+ virt_text = {
+ {
+ string.rep(" " or pad_char, left_padding),
+ utils.set_hl(config.border_hl)
+ }
+ }
+ });
+ end
+
+ -- Calculating the amount of spacing to add,
+ -- 1. Used space = label width(`label_width`) + padding size(`pad_width`).
+ -- 2. Total block width - Used space
+ local spacing = block_width - (label_width + pad_width);
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start + #item.text[1], {
+ virt_text_pos = "inline",
+ virt_text = {
+ {
+ string.rep(pad_char, spacing),
+ utils.set_hl(config.border_hl)
+ },
+ }
+ });
+
+ ---|fS "chunk: Place label"
+
+ local top_border = {
+ };
+
+ if config.label_direction == "right" then
+ top_border.col_start = range.start_delim[2] + #item.text[1];
+ else
+ top_border.col_start = range.start_delim[4];
+ end
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, top_border.col_start, {
+ virt_text_pos = "inline",
+ virt_text = { label }
+ });
+
+ ---|fE
+
+ ---|fE
+
+ --- Line padding
+ for l, width in ipairs(line_widths) do
+ local line = item.text[l + 1];
+ local line_config = get_line_config(line);
+
+ if width ~= 0 then
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start + l, line ~= "" and range.col_start or 0, {
+ undo_restore = false, invalidate = true,
+
+ virt_text_pos = "inline",
+ virt_text = {
+ {
+ string.rep(" ", pad_amount),
+ utils.set_hl(line_config.pad_hl --[[ @as string ]])
+ }
+ },
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start + l, range.col_start + #line, {
+ undo_restore = false, invalidate = true,
+
+ virt_text_pos = "inline",
+ virt_text = {
+ {
+ string.rep(" ", math.max(0, block_width - (( 2 * pad_amount) + width))),
+ utils.set_hl(line_config.block_hl --[[ @as string ]])
+ },
+ {
+ string.rep(" ", pad_amount),
+ utils.set_hl(line_config.pad_hl --[[ @as string ]])
+ }
+ },
+ });
+
+ --- Background
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start + l, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_col = range.col_start + #line,
+
+ hl_group = utils.set_hl(line_config.block_hl --[[ @as string ]])
+ });
+ else
+ local buf_line = vim.api.nvim_buf_get_lines(buffer, range.row_start + l, range.row_start + l + 1, false)[1];
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start + l, #buf_line, {
+ undo_restore = false, invalidate = true,
+
+ virt_text_pos = "inline",
+ virt_text = {
+ {
+ string.rep(" ", math.max(0, range.col_start - #buf_line))
+ },
+ {
+ string.rep(" ", pad_amount),
+ utils.set_hl(line_config.pad_hl --[[ @as string ]])
+ },
+ {
+ string.rep(" ", math.max(0, block_width - (2 * pad_amount))),
+ utils.set_hl(line_config.block_hl --[[ @as string ]])
+ },
+ {
+ string.rep(" ", pad_amount),
+ utils.set_hl(line_config.pad_hl --[[ @as string ]])
+ },
+ },
+ });
+ end
+ end
+
+ --- Render bottom
+ local end_delim_conceal_from = range.end_delim[2] + #string.match(item.delimiters[2], "^%s*");
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_end, end_delim_conceal_from, {
+ undo_restore = false, invalidate = true,
+ end_col = range.col_start + #item.text[#item.text],
+ conceal = ""
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_end, end_delim_conceal_from, {
+ undo_restore = false, invalidate = true,
+
+ virt_text_pos = "inline",
+ virt_text = {
+ {
+ string.rep(" ", block_width),
+ utils.set_hl(config.border_hl)
+ }
+ }
+ });
+
+ ---|fE
+ end
+
+ if not win or config.style == "simple" or item.uses_tab or ( vim.o.wrap == true or vim.wo[win].wrap == true ) then
+ render_simple();
+ elseif config.style == "block" then
+ render_block()
+ end
+
+ ---|fE
+end
+
+---@param buffer integer
+---@param item markview.parsed.comment.urls
+comment.url = function (buffer, item)
+ ---|fS
+
+ ---@type markview.config.comment.urls?
+ local main_config = spec.get({ "comment", "urls" }, { fallback = nil });
+
+ if not main_config then
+ return;
+ end
+
+ ---@type markview.config.comments.urls.opts?
+ local config = utils.match(main_config, item.destination or "", {
+ ignore_keys = { "enable" },
+ eval_args = { buffer, item }
+ });
+
+ if not config then
+ return;
+ end
+
+ local range = item.range;
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_col = config.text and range.col_end or nil,
+ conceal = config.text and "" or nil,
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.corner_left or "", utils.set_hl(config.corner_left_hl or config.hl) },
+ { config.padding_left or "", utils.set_hl(config.padding_left_hl or config.hl) },
+
+ { config.icon or "", utils.set_hl(config.icon_hl or config.hl) },
+ config.text and { config.text, utils.set_hl(config.text_hl or config.hl) } or nil,
+ },
+
+ hl_mode = "combine"
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_row = range.row_end,
+ end_col = range.col_end,
+
+ hl_group = utils.set_hl(config.hl)
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_end, range.col_end, {
+ undo_restore = false, invalidate = true,
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.padding_right or "", utils.set_hl(config.padding_right_hl or config.hl) },
+ { config.corner_right or "", utils.set_hl(config.corner_right_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ ---|fE
+end
+
+---@param buffer integer
+---@param item markview.parsed.comment.taglinks
+comment.taglink = function (buffer, item)
+ ---|fS
+
+ ---@type markview.config.comment.taglinks?
+ local main_config = spec.get({ "comment", "taglinks" }, { fallback = nil });
+
+ if not main_config then
+ return;
+ end
+
+ ---@type markview.config.__inline?
+ local config = utils.match(main_config, item.text[1] or "", {
+ ignore_keys = { "enable" },
+ eval_args = { buffer, item }
+ });
+
+ if not config then
+ return;
+ end
+
+ local range = item.range;
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_col = range.col_start + 1,
+ conceal = "",
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.corner_left or "", utils.set_hl(config.corner_left_hl or config.hl) },
+ { config.padding_left or "", utils.set_hl(config.padding_left_hl or config.hl) },
+
+ { config.icon or "", utils.set_hl(config.icon_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_row = range.row_end,
+ end_col = range.col_end,
+
+ hl_group = utils.set_hl(config.hl)
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_end, range.col_end - 1, {
+ undo_restore = false, invalidate = true,
+ end_col = range.col_end,
+ conceal = "",
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.padding_right or "", utils.set_hl(config.padding_right_hl or config.hl) },
+ { config.corner_right or "", utils.set_hl(config.corner_right_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ ---|fE
+end
+
+---@param buffer integer
+---@param item markview.parsed.comment.inline_codes
+comment.bold = function (buffer, item)
+ ---|fS
+
+ ---@type markview.config.comment.bolds?
+ local config = spec.get({ "comment", "bolds" }, { fallback = nil });
+
+ if not config then
+ return;
+ end
+
+ local range = item.range;
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_col = range.col_start + 2,
+ conceal = "",
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.corner_left or "", utils.set_hl(config.corner_left_hl or config.hl) },
+ { config.padding_left or "", utils.set_hl(config.padding_left_hl or config.hl) },
+
+ { config.icon or "", utils.set_hl(config.icon_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_row = range.row_end,
+ end_col = range.col_end,
+
+ hl_group = utils.set_hl(config.hl)
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_end, range.col_end - 2, {
+ undo_restore = false, invalidate = true,
+ end_col = range.col_end,
+ conceal = "",
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.padding_right or "", utils.set_hl(config.padding_right_hl or config.hl) },
+ { config.corner_right or "", utils.set_hl(config.corner_right_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ ---|fE
+end
+
+---@param buffer integer
+---@param item markview.parsed.comment.inline_codes
+comment.italic = function (buffer, item)
+ ---|fS
+
+ ---@type markview.config.comment.italics?
+ local config = spec.get({ "comment", "italics" }, { fallback = nil });
+
+ if not config then
+ return;
+ end
+
+ local range = item.range;
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_col = range.col_start + 1,
+ conceal = "",
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.corner_left or "", utils.set_hl(config.corner_left_hl or config.hl) },
+ { config.padding_left or "", utils.set_hl(config.padding_left_hl or config.hl) },
+
+ { config.icon or "", utils.set_hl(config.icon_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_start, range.col_start, {
+ undo_restore = false, invalidate = true,
+ end_row = range.row_end,
+ end_col = range.col_end,
+
+ hl_group = utils.set_hl(config.hl)
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, comment.ns, range.row_end, range.col_end - 1, {
+ undo_restore = false, invalidate = true,
+ end_col = range.col_end,
+ conceal = "",
+
+ virt_text_pos = "inline",
+ virt_text = {
+ { config.padding_right or "", utils.set_hl(config.padding_right_hl or config.hl) },
+ { config.corner_right or "", utils.set_hl(config.corner_right_hl or config.hl) }
+ },
+
+ hl_mode = "combine"
+ });
+
+ ---|fE
+end
+
+--- Renders fancy comments
+---@param buffer integer
+---@param content markview.parsed.comment[]
+comment.render = function (buffer, content)
+ ---|fS
+
+ local custom = spec.get({ "renderers" }, { fallback = {} });
+
+ for _, item in ipairs(content or {}) do
+ local success, err;
+
+ if custom[item.class] then
+ success, err = pcall(custom[item.class], comment.ns, buffer, item);
+ else
+ success, err = pcall(comment[item.class:gsub("^comment_", "")], buffer, item);
+ end
+
+ if success == false then
+ require("markview.health").print({
+ kind = "ERR",
+
+ from = "renderers/comment.lua",
+ fn = "render() -> " .. item.class,
+
+ message = {
+ { tostring(err), "DiagnosticError" }
+ }
+ });
+ end
+ end
+
+ ---|fE
+end
+
+--- Clears decorations of fancy comments
+---@param buffer integer
+---@param from integer
+---@param to integer
+comment.clear = function (buffer, from, to)
+ vim.api.nvim_buf_clear_namespace(buffer, comment.ns, from or 0, to or -1);
+end
+
+return comment;
diff --git a/lua/markview/spec.lua b/lua/markview/spec.lua
index f69294c..d35690f 100644
--- a/lua/markview/spec.lua
+++ b/lua/markview/spec.lua
@@ -8,6 +8,8 @@ local spec = {};
---@type markview.config
spec.default = {
experimental = {
+ fancy_comments = false,
+
date_formats = {
"^%d%d%d%d%-%d%d%-%d%d$", --- YYYY-MM-DD
"^%d%d%-%d%d%-%d%d%d%d$", --- DD-MM-YYYY, MM-DD-YYYY
@@ -187,8 +189,23 @@ spec.default = {
debounce = 150,
icon_provider = "internal",
- filetypes = { "markdown", "quarto", "rmd", "typst" },
+ filetypes = { "markdown", "quarto", "rmd", "typst", },
ignore_buftypes = { "nofile" },
+ condition = function (buffer)
+ local is_enabled = spec.get({ "experimental", "fancy_comments" }, {
+ fallback = false,
+ });
+
+ if not is_enabled then
+ return false;
+ end
+
+ local success, parser = pcall(vim.treesitter.get_parser, buffer);
+ if success and parser ~= nil then
+ return true;
+ end
+ end,
+
raw_previews = {},
modes = { "n", "no", "c" },
@@ -210,6 +227,7 @@ spec.default = {
---@type string[] Properties that should be sourced *externally*.
spec.__external_config = {
+ "comment",
"html",
"markdown",
"markdown_inline",
diff --git a/lua/markview/types/experimental.lua b/lua/markview/types/experimental.lua
index c693694..ac3356a 100644
--- a/lua/markview/types/experimental.lua
+++ b/lua/markview/types/experimental.lua
@@ -3,6 +3,8 @@
--- Experimental options.
---@class markview.config.experimental
---
+---@field fancy_comments boolean When `true`, enables preview on **all buffers** with an active `tree-sitter parser`.
+---
---@field date_formats string[] List of lua patterns for detecting date in YAML.
---@field date_time_formats string[] List of lua patterns for detecting date & time in YAML.
---
diff --git a/lua/markview/types/markview.lua b/lua/markview/types/markview.lua
index ecc1f72..c814423 100644
--- a/lua/markview/types/markview.lua
+++ b/lua/markview/types/markview.lua
@@ -100,6 +100,7 @@
--- Maps a `node_type` to an option name.
---@class markview.renderer.option_maps
---
+---@field comment markview.renderer.option_map
---@field html markview.renderer.option_map
---@field latex markview.renderer.option_map
---@field markdown markview.renderer.option_map
diff --git a/lua/markview/types/parsers/comment.lua b/lua/markview/types/parsers/comment.lua
new file mode 100644
index 0000000..b2a6f83
--- /dev/null
+++ b/lua/markview/types/parsers/comment.lua
@@ -0,0 +1,158 @@
+---@meta
+
+------------------------------------------------------------------------------
+
+--[[
+An autolink.
+
+```comment
+
+```
+]]
+---@class markview.parsed.comment.autolinks
+---
+---@field class "comment_autolink"
+---@field destination string Text between `<>`.
+---
+---@field text string
+---@field range markview.parsed.range
+
+------------------------------------------------------------------------------
+
+--- A `task`.
+---@class markview.parsed.comment.tasks
+---
+---@field class "comment_task"
+---
+---@field kind string Type of task(e.g. `feat`, `TODO` etc.)
+---@field text string
+---@field range markview.parsed.comment.tasks.range
+
+
+---@class markview.parsed.comment.tasks.range
+---
+---@field label_row_end? integer End row of a label(A label may be like `foo:`, `bar(topic):`).
+---@field label_col_end? integer End column of a label(A label may be like `foo:`, `bar(topic):`).
+---
+---@field kind integer[] Range of the `task kind`(result of `{ TSNode:range() }`).
+---
+---@field row_start integer
+---@field row_end integer
+---@field col_start integer
+---@field col_end integer
+
+------------------------------------------------------------------------------
+
+--- A `task` scope.
+---@class markview.parsed.comment.task_scopes
+---
+---@field class "comment_task_scopes"
+---
+---@field text string
+---@field range markview.parsed.comment.tasks.range
+
+------------------------------------------------------------------------------
+
+--- An issue reference.
+---@class markview.parsed.comment.issues
+---
+---@field class "comment_issue"
+---
+---@field text string
+---@field range markview.parsed.range
+
+------------------------------------------------------------------------------
+
+--- An URL.
+---@class markview.parsed.comment.urls
+---
+---@field class "comment_url"
+---@field destination string
+---
+---@field text string
+---@field range markview.parsed.range
+
+------------------------------------------------------------------------------
+
+--- A taglink.
+---@class markview.parsed.comment.taglinks
+---
+---@field class "comment_taglink"
+---
+---@field text string
+---@field range markview.parsed.range
+
+------------------------------------------------------------------------------
+
+--- A mention.
+---@class markview.parsed.comment.mentions
+---
+---@field class "comment_mention"
+---
+---@field text string
+---@field range markview.parsed.range
+
+------------------------------------------------------------------------------
+
+--- A mention.
+---@class markview.parsed.comment.inline_codes
+---
+---@field class "comment_inline_code"
+---
+---@field text string
+---@field range markview.parsed.range
+
+------------------------------------------------------------------------------
+
+---@class markview.parsed.comment.code_blocks
+---
+---@field class "markdown_code_block"
+---@field uses_tab boolean Does the code block use tab inside it? Used for switching render style.
+---
+---@field delimiters [ string, string ] Code block delimiters(```).
+---@field language string? Language string(typically after ```).
+---@field info_string string? Extra information(typically after the language).
+---
+---@field text string[]
+---@field range markview.parsed.comment.code_blocks.range
+
+
+---@class markview.parsed.comment.code_blocks.range
+---
+---@field start_delim integer[] Range of the **start** delimiter.
+---@field end_delim? integer[] Range of the **end** delimiter.
+---
+---@field row_start integer
+---@field row_end integer
+---@field col_start integer
+---@field col_end integer
+---
+---@field language? integer[] Range of the language string.
+---@field info_string? integer[] Range of info string.
+
+------------------------------------------------------------------------------
+
+---@alias markview.parsed.comment
+---| markview.parsed.comment.autolinks
+---| markview.parsed.comment.code_blocks
+---| markview.parsed.comment.inline_codes
+---| markview.parsed.comment.issues
+---| markview.parsed.comment.mentions
+---| markview.parsed.comment.taglinks
+---| markview.parsed.comment.tasks
+---| markview.parsed.comment.task_scopes
+---| markview.parsed.comment.urls
+
+
+---@class markview.parsed.comment_sorted
+---
+---@field autolinks markview.parsed.comment.autolinks[]
+---@field code_blocks markview.parsed.comment.code_blocks[]
+---@field inline_codes markview.parsed.comment.inline_codes[]
+---@field issues markview.parsed.comment.issues[]
+---@field mentions markview.parsed.comment.mentions[]
+---@field taglinks markview.parsed.comment.taglinks[]
+---@field tasks markview.parsed.comment.tasks[]
+---@field task_scopes markview.parsed.comment.task_scopes[]
+---@field urls markview.parsed.comment.urls[]
+
diff --git a/lua/markview/types/preview.lua b/lua/markview/types/preview.lua
index 9f4888a..dfa5574 100644
--- a/lua/markview/types/preview.lua
+++ b/lua/markview/types/preview.lua
@@ -22,7 +22,7 @@
---@field ignore_buftypes? string[] Buftypes that should be ignored(e.g. nofile).
---@field raw_previews? markview.config.preview.raw Options that will show up as raw in hybrid mode.
---
----@field condition? fun(buffer: integer): boolean Condition to check if a buffer should be attached or not.
+---@field condition? fun(buffer: integer): boolean? Condition to check if a buffer should be attached or not. Overrides `preview.filetypes` & `preview.ignore_buftypes`. If `nil` is returned, `preview.filetypes` & `preview.ignore_buftypes` are checked.
---
---@field modes? string[] Vim-modes where previews will be shown.
---@field hybrid_modes? string[] Vim-modes where `hybrid mode` is enabled. Options that should/shouldn't be previewed in `hybrid_modes`.
@@ -58,6 +58,7 @@
--- in `hybrid mode`.
---@class markview.config.preview.raw
---
+---@field comment? markview.config.preview.raw.comment[]
---@field html? markview.config.preview.raw.html[]
---@field latex? markview.config.preview.raw.latex[]
---@field markdown? markview.config.preview.raw.markdown[]
@@ -65,6 +66,27 @@
---@field typst? markview.config.preview.raw.typst[]
---@field yaml? markview.config.preview.raw.yaml[]
+---@alias markview.config.preview.raw.comment
+---| "!autolinks"
+---| "!code_blocks"
+---| "!inline_codes"
+---| "!issues"
+---| "!mentions"
+---| "!taglinks"
+---| "!task_scopes"
+---| "!tasks"
+---| "!urls"
+---
+---| "autolinks"
+---| "code_blocks"
+---| "inline_codes"
+---| "issues"
+---| "mentions"
+---| "taglinks"
+---| "task_scopes"
+---| "tasks"
+---| "urls"
+
---@alias markview.config.preview.raw.html
---| "!container_elements"
---| "!headings"
diff --git a/lua/markview/types/renderers/comment.lua b/lua/markview/types/renderers/comment.lua
new file mode 100644
index 0000000..53afc21
--- /dev/null
+++ b/lua/markview/types/renderers/comment.lua
@@ -0,0 +1,226 @@
+---@meta
+
+------------------------------------------------------------------------------
+
+--[[ Configuration for `comments`. ]]
+---@class markview.config.comment
+---
+---@field enable boolean Enable **comment** rendering.
+---
+---@field autolinks markview.config.comment.autolinks
+---@field code_blocks markview.config.comment.code_blocks
+---@field inline_codes markview.config.comment.inline_codes
+---@field issues markview.config.comment.issues
+---@field mentions markview.config.comment.mentions
+---@field taglinks markview.config.comment.taglinks
+---@field tasks markview.config.comment.tasks
+---@field task_scopes markview.config.comment.task_scopes
+---@field urls markview.config.comment.urls
+
+------------------------------------------------------------------------------
+
+---@class markview.config.comment.tasks
+---
+---@field enable boolean
+---
+---@field default markview.config.comment.tasks.opts
+---@field [string] markview.config.comment.tasks.opts
+
+
+---@class markview.config.comment.tasks.opts markview.config.__inline
+---
+---@field corner_left? string Left corner.
+---@field corner_left_hl? string Highlight group for the left corner.
+---
+---@field padding_left? string Left padding(added after `corner_left`).
+---@field padding_left_hl? string Highlight group for the left padding.
+---
+---@field icon? string Icon(added after `padding_left`).
+---@field icon_hl? string Highlight group for the icon.
+---
+---@field hl? string Default highlight group(used by `*_hl` options when they are not set).
+---@field desc_hl? string Highlight group for the `description`.
+---
+---@field padding_right? string Right padding.
+---@field padding_right_hl? string Highlight group for the right padding.
+---
+---@field corner_right? string Right corner(added after `padding_right`).
+---@field corner_right_hl? string Highlight group for the right corner.
+
+------------------------------------------------------------------------------
+
+---@alias markview.config.comment.inline_codes markview.config.__inline
+
+------------------------------------------------------------------------------
+
+--- Configuration for code blocks.
+---@alias markview.config.comment.code_blocks
+---| markview.config.comment.code_blocks.simple
+---| markview.config.comment.code_blocks.block
+
+
+---@class markview.config.comment.code_blocks.simple
+---
+---@field enable boolean Enable rendering of code blocks.
+---
+---@field border_hl? string Highlight group for borders.
+---@field info_hl? string Highlight group for the info string.
+---
+---@field label_direction? "left" | "right" Position of the language & icon.
+---@field label_hl? string Highlight group for the label.
+---
+---@field sign? boolean Enables signs for the code block?
+---@field sign_hl? string Highlight group for the sign.
+---
+---@field style "simple" Only highlights the line. Enabled when `wrap` is enabled.
+---
+---@field default markview.config.comment.code_blocks.opts
+---@field [string] markview.config.comment.code_blocks.opts
+
+
+---@class markview.config.comment.code_blocks.block
+---
+---@field enable boolean Enable rendering of code blocks.
+---
+---@field border_hl? string Highlight group for borders.
+---@field info_hl? string Highlight group for the info string.
+---
+---@field label_direction? "left" | "right" Position of the language & icon.
+---@field label_hl? string Highlight group for the label.
+---
+---@field min_width? integer Minimum width of the code block.
+---@field pad_amount? integer Number of `pad_char`s to add on the left & right side of the code block.
+---@field pad_char? string Character used as padding.
+---
+---@field sign? boolean Enables signs for the code block?
+---@field sign_hl? string Highlight group for the sign.
+---
+---@field style "block" Creates a block around the code block. Disabled when `wrap` is enabled.
+---
+---@field default markview.config.comment.code_blocks.opts
+---@field [string] markview.config.comment.code_blocks.opts
+
+
+--[[ Configuration for highlighting `lines` inside a code block. ]]
+---@class markview.config.comment.code_blocks.opts
+---
+---@field block_hl
+---| string Highlight group for the background of the line.
+---| fun(buffer: integer, line: string): string? Takes `line` & the `buffer` containing it and returns a highlight group for the line.
+---@field pad_hl
+---| string Highlight group for the padding of the line.
+---| fun(buffer: integer, line: string): string? Takes `line` & the `buffer` containing it and returns a highlight group for the padding..
+
+------------------------------------------------------------------------------
+
+--- Configuration for issues.
+---@class markview.config.comment.issues
+---
+---@field enable boolean Enable rendering of `#issue`s.
+---
+---@field default markview.config.__inline Default configuration for issues.
+---@field [string] markview.config.__inline Configuration for issues whose text matches with the key's pattern.
+
+------------------------------------------------------------------------------
+
+--- Configuration for mentions.
+---@class markview.config.comment.mentions
+---
+---@field enable boolean Enable rendering of `@mention`s.
+---
+---@field default markview.config.__inline Default configuration for mentions.
+---@field [string] markview.config.__inline Configuration for mentions whose text matches with the key's pattern.
+
+------------------------------------------------------------------------------
+
+--- Configuration for task_scopes.
+---@class markview.config.comment.task_scopes
+---
+---@field enable boolean Enable rendering of `task scope`s.
+---
+---@field default markview.config.__inline Default configuration for mentions.
+---@field [string] markview.config.__inline Configuration for scopes matching the key's pattern.
+
+------------------------------------------------------------------------------
+
+--- Configuration for URLs.
+---@class markview.config.comment.urls
+---
+---@field enable boolean Enable rendering of `URL`s.
+---
+---@field default markview.config.comments.urls.opts Default configuration for URLs.
+---@field [string] markview.config.comments.urls.opts Configuration for URLs whose text matches with the key's pattern.
+
+
+---@class markview.config.comments.urls.opts
+---
+---@field corner_left? string Left corner.
+---@field corner_left_hl? string Highlight group for the left corner.
+---
+---@field padding_left? string Left padding(added after `corner_left`).
+---@field padding_left_hl? string Highlight group for the left padding.
+---
+---@field icon? string Icon(added after `padding_left`).
+---@field icon_hl? string Highlight group for the icon.
+---
+--[[ Text to show instead of the `autolink`.]]
+---@field text?
+---| string
+---| function(buffer: integer, item: markview.parsed.comment.autolinks): string
+---@field text_hl? string Highlight group for the shown text.
+---
+---@field hl? string Default highlight group(used by `*_hl` options when they are not set).
+---
+---@field padding_right? string Right padding.
+---@field padding_right_hl? string Highlight group for the right padding.
+---
+---@field corner_right? string Right corner(added after `padding_right`).
+---@field corner_right_hl? string Highlight group for the right corner.
+
+
+------------------------------------------------------------------------------
+
+--- Configuration for taglinks.
+---@class markview.config.comment.taglinks
+---
+---@field enable boolean Enable rendering of `|taglink|`s.
+---
+---@field default markview.config.__inline Default configuration.
+---@field [string] markview.config.__inline Configuration for taglinks matching the key's pattern.
+
+------------------------------------------------------------------------------
+
+--- Configuration for autolinks.
+---@class markview.config.comment.autolinks
+---
+---@field enable boolean Enable rendering of ``s.
+---
+---@field default markview.config.comments.autolinks.opts Default configuration.
+---@field [string] markview.config.comments.autolinks.opts Configuration for autolinks matching the key's pattern.
+
+
+---@class markview.config.comments.autolinks.opts
+---
+---@field corner_left? string Left corner.
+---@field corner_left_hl? string Highlight group for the left corner.
+---
+---@field padding_left? string Left padding(added after `corner_left`).
+---@field padding_left_hl? string Highlight group for the left padding.
+---
+---@field icon? string Icon(added after `padding_left`).
+---@field icon_hl? string Highlight group for the icon.
+---
+--[[ Text to show instead of the `autolink`.]]
+---@field text?
+---| string
+---| function(buffer: integer, item: markview.parsed.comment.autolinks): string
+---@field text_hl? string Highlight group for the shown text.
+---
+---@field hl? string Default highlight group(used by `*_hl` options when they are not set).
+---
+---@field padding_right? string Right padding.
+---@field padding_right_hl? string Highlight group for the right padding.
+---
+---@field corner_right? string Right corner(added after `padding_right`).
+---@field corner_right_hl? string Highlight group for the right corner.
+
diff --git a/lua/markview/utils.lua b/lua/markview/utils.lua
index 2acd916..50f5a65 100644
--- a/lua/markview/utils.lua
+++ b/lua/markview/utils.lua
@@ -287,11 +287,20 @@ utils.create_user_command_class = function (config)
return class;
end
+---@class markview.utils.match.opts
+---
+---@field case_insensitive? boolean
+---@field def_fallback? any
+---@field default? boolean
+---@field eval_args any[]
+---@field ignore_keys? any[]
+---@field key_mod? string
+
--- Gets a config from a list of config tables.
--- NOTE, {name} will be used to index the config.
---@param config table
---@param name string
----@param opts { key_mod: string?, default: boolean, def_fallback: any?, eval_args: any[], ignore_keys?: any[] }
+---@param opts markview.utils.match.opts
---@return any
utils.match = function (config, name, opts)
config = config or {};
@@ -347,15 +356,22 @@ utils.match = function (config, name, opts)
local function is_valid (value, pattern)
local ignore = opts.ignore_keys or { "enable" };
+
+ local _value = value;
local _pattern = pattern;
if opts.key_mod then
_pattern = string.format(opts.key_mod, _pattern);
end
+ if opts.case_insensitive and type(_value) == "string" then
+ _value = string.lower(_value);
+ _pattern = string.lower(_pattern);
+ end
+
if vim.list_contains(ignore, pattern) then
return false;
- elseif string.match(value, _pattern) then
+ elseif string.match(_value, _pattern) then
return true;
else
return false;
diff --git a/markview.nvim.wiki b/markview.nvim.wiki
index 2f6e9a4..df2d1c2 160000
--- a/markview.nvim.wiki
+++ b/markview.nvim.wiki
@@ -1 +1 @@
-Subproject commit 2f6e9a41e27163e59fba3513eafd9ec156d13d71
+Subproject commit df2d1c2f2e1820b5e8dd81e5360e3699a0c98581
diff --git a/test/comment.lua b/test/comment.lua
new file mode 100644
index 0000000..057def4
--- /dev/null
+++ b/test/comment.lua
@@ -0,0 +1,32 @@
+--[[
+feat(@OXY2DEV): Tree-sitter parser for `Conventional comments`.
+
+A `tree-sitter` parser for **conventional comments** that supports a subset of `markdown`.
+It can be used as an injected language for other parsers(e.g. for comments).
+
+The parser currently supports,
+
+ âą **Bold**
+ âą *Italic*
+ âą `Code`
+ âą 'Quoted_text'
+ âą "Double quoted text"
+ âą @mentions
+ âą issues/reference#52
+ âą https://example.com
+ âą |help-section|
+
+```lua
+print("Hello, world!");
+```
+
+With support for *common comment topics* such as,
+
+todo: Some task.
+FIXME: Fix some *issues*.
+
+NOTE(grammar, @OXY2DEV): Add features to grammar.
+
+Author: @OXY2DEV
+]]
+local a = 1;