diff --git a/.github/workflows/luarocks.yml b/.github/workflows/luarocks.yml
new file mode 100644
index 0000000..c927624
--- /dev/null
+++ b/.github/workflows/luarocks.yml
@@ -0,0 +1,42 @@
+name: Luarocks
+
+on:
+ push:
+ tags:
+ - '*'
+ release:
+ types:
+ - created
+ pull_request: # Tests packaging on PR
+ workflow_dispatch:
+
+jobs:
+ luarocks-upload:
+ runs-on: ubuntu-22.04
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0 # Required to get the tags
+ - name: Get Version
+ run: echo "LUAROCKS_VERSION=$(git describe --abbrev=0 --tags)" >> $GITHUB_ENV
+
+ # Needed to build the tree-sitter parser dependencies
+ - name: Install C/C++ Compiler
+ uses: rlalik/setup-cpp-compiler@master
+ with:
+ compiler: clang-latest
+ - name: Install tree-sitter CLI
+ uses: baptiste0928/cargo-install@v3
+ with:
+ crate: tree-sitter-cli
+
+ - name: LuaRocks Upload
+ uses: nvim-neorocks/luarocks-tag-release@v7
+ env:
+ LUAROCKS_API_KEY: ${{ secrets.LUAROCKS_API_KEY }}
+ with:
+ version: ${{ env.LUAROCKS_VERSION }}
+ dependencies: |
+ tree-sitter-markdown
+ nvim-web-devicons
+
diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml
new file mode 100644
index 0000000..933c9f9
--- /dev/null
+++ b/.github/workflows/release-please.yml
@@ -0,0 +1,27 @@
+# vim:nospell:
+name: Release Please
+
+on:
+ push:
+ branches:
+ - dev
+
+permissions:
+ contents: write
+ pull-requests: write
+
+jobs:
+ release-please:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: googleapis/release-please-action@v4
+ with:
+ # this assumes that you have created a personal access token
+ # (PAT) and configured it as a GitHub action secret named
+ # `MY_RELEASE_PLEASE_TOKEN` (this secret name is not important).
+ token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
+ # this is a built-in strategy in release-please, see "Action Inputs"
+ # for more options
+
+ target-branch: dev
+ release-type: simple
diff --git a/.gitmodules b/.gitmodules
index 203bc8a..7a4def7 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
[submodule "wiki"]
path = wiki
url = https://github.com/OXY2DEV/markview.nvim.wiki.git
+[submodule "markview.nvim.wiki"]
+ path = markview.nvim.wiki
+ url = https://github.com/OXY2DEV/markview.nvim.wiki.git
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 892400b..c01fc31 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,30 @@
# Changelog
-## 1.0.0 (2024-07-31)
+## [19.0.0](https://github.com/OXY2DEV/markview.nvim/compare/v18.0.0...v19.0.0) (2024-08-05)
+### ⚠ BREAKING CHANGES
+
+* **renderer:** Added support for simple html elements
+* **renderer:** Support for tables that don't start at the start of the line
+
### Features
+* Added support for HTML entites ([3b270c1](https://github.com/OXY2DEV/markview.nvim/commit/3b270c1dedbf02b4849341ff9e490a001041e248))
+* **renderer:** Added basic language names to code blocks ([c9b4f77](https://github.com/OXY2DEV/markview.nvim/commit/c9b4f77e880eb0ab9afd370ad82e3758513a4a3a)), closes [#72](https://github.com/OXY2DEV/markview.nvim/issues/72)
+* **renderer:** Added better validation for html tags in table cells ([ab0e54e](https://github.com/OXY2DEV/markview.nvim/commit/ab0e54e2992b3806fe2b3a68a49d050f1118159e))
+* **renderer:** Added hybrid-mode support to the plugin ([4a93e15](https://github.com/OXY2DEV/markview.nvim/commit/4a93e155261508b89d5c6146ba6cc0da91be0883)), closes [#64](https://github.com/OXY2DEV/markview.nvim/issues/64)
+* **renderer:** Added support for simple html elements ([94ce522](https://github.com/OXY2DEV/markview.nvim/commit/94ce522302f78167e278d3c7d82ff0206c74b4e3))
+* **renderer:** Support for tables that don't start at the start of the line ([3c8b0dc](https://github.com/OXY2DEV/markview.nvim/commit/3c8b0dc5a9b02264f94137b23279db7d3198ac7a))
* replace tbl_islist to islist ([f1e66c7](https://github.com/OXY2DEV/markview.nvim/commit/f1e66c78ba28b3b2399a4b76febc42ceb3211fd1))
+
+
+### Bug Fixes
+
+* **parser:** Added logic for supporting markers inside code blocks ([a38dd1f](https://github.com/OXY2DEV/markview.nvim/commit/a38dd1f01c31b4201b4355fe8ebaa439621e5b35)), closes [#69](https://github.com/OXY2DEV/markview.nvim/issues/69)
+* **parser:** Improved validation of pending checkboxes ([a6392dd](https://github.com/OXY2DEV/markview.nvim/commit/a6392ddeb627a4ebd218718bc4f80b5fca1a1803))
+* **renderer:** Fixed a bug causing inconsistency between the left & right padding in inline codes ([0eb84e5](https://github.com/OXY2DEV/markview.nvim/commit/0eb84e5721dfd2ded1c598eba3ec018d5fd1cd9d))
+* **renderer:** Fixed a bug causing the last line to have border placed on the wrong column ([e102b06](https://github.com/OXY2DEV/markview.nvim/commit/e102b060907173fcafaa8e5e4edde993452a9808))
+* **renderer:** Fixed a bug leading to extmarks on the current line not being removed ([777c6aa](https://github.com/OXY2DEV/markview.nvim/commit/777c6aa50d623eed5a17fb39be60f23fbc7bd4bc))
+* **renderer:** Fixed screen not updating in "no" mode ([60bc13b](https://github.com/OXY2DEV/markview.nvim/commit/60bc13b9492570d4d321391517eb9677918f540e)), closes [#70](https://github.com/OXY2DEV/markview.nvim/issues/70)
+* **renderer:** Made headings use decorations around the text instead of replacing the main text ([41d57ab](https://github.com/OXY2DEV/markview.nvim/commit/41d57ab40603b702cd7b7b920c71f7b20ba202aa))
diff --git a/README.md b/README.md
index 4709425..b16ded7 100644
--- a/README.md
+++ b/README.md
@@ -1,86 +1,94 @@
# 📜 Markview.nvim
-
Simple markdown previewer for neovim
+An experimental `markdown` previewer for Neovim.
->[!IMPORTANT]
-> Presets have been reworked, though you can still use the old presets. It is recommended that you switch to the newer ones as the old ones will be removed in the future.
+
+ Wiki page
+
-![headings](./images/headings.jpg)
-![lists](./images/lists.jpg)
-![tables](./images/tables.jpg)
+![hybrid_mode_showcase](https://github.com/OXY2DEV/markview.nvim/blob/images/Main/hybrid_mode_showcase.gif)
+![html_showcase](https://github.com/OXY2DEV/markview.nvim/blob/images/Main/html_showcase.gif)
+![screenshot](https://github.com/OXY2DEV/markview.nvim/blob/images/Main/plugin_showcase_landscape.jpg)
+![screenshot_small](https://github.com/OXY2DEV/markview.nvim/blob/images/Main/plugin_showcase_mobile.jpg)
->[!WARNING]
-> This plugin is in it's alpha stage and may go through breaking changes.
+## ✨ Features
->[!IMPORTANT]
-> Highlights now use `PascalCase` so it is recommended to change your highlight group names to PascalCase. But don't worry, the previous names using `Markview_` are still supported!
+Markview.nvim comes with a ton of features such as,
-## 📑 Table of contents
+- Close to `full render` of markdown documents. Currently supported items are,
+ * Block quotes(includes `callouts`/`alerts`
+ * Chekboxes(checked, unchecked & pending state)
+ * Headings(atx_headings & setext_headings)
+ * Horizontal rules
+ * Html support(only for simple tags, e.g. `Underline`)
+ * Html entites(both `&;` and `&` support)
+ * Inline codes
+ * Links(hyprlinks, images & email support)
+ * List item(ordered & unordered)
+ * Tables
+- Fully customisable setup! You can customise everything to your needs!
+- A `hybrid mode` that allows rendering in real-time! It will even unconceal nodes under the cursor.
+- Dynamic `highlight groups` that allows support for almost any colorscheme!
+- Can be loaded on other filetypes too!
-- [Features](#-features)
-- [Requirements](#-requirements)
-- [Installation](#-installation)
- - [Lazy.nvim](#-lazynvim)
- - [Mini.deps](#-minideps)
- - [Others](#-others)
-- [Setup](#-setup)
-- [Commands](#-commands)
-- [Showcases](#-showcases)
+And a lot more to come!
-## 🛸 Features
+## 📦 Requirements
-- Fully customisable markdown `headings`.
-- Custom `block quotes` with support for `callouts` & `alerts`.
-- Custom `code blocks` with different style supports.
-- Statusline-like `horizontal rules` customisation.
-- Custom `links` and `image links`.
-- Custom `inline codes`.
-- Padded list items(with nested list support).
-- Custom `checkboxes` for different checkbox states.
-- Fully customisable `tables`.
+- Neovim version: `0.10.0` or above.
+- Tree-sitter parsers,
+ * markdown
+ * markdown_inline
+ * html
+- Nerd font.
-## 🔭 Requirements
+Optional:
+- A tree-sitter supported colorscheme.
-- Neovim version: 0.10 or higher(unless API changes occurred).
-- `nvim-treesitter` for easy installation of treesitter parsers.
-- `markdown` and `markdown_inline` treesitter parsers.
-- `nvim-web-devicons` for the icons.
+## 🚀 Installation
-## 📦 Installation
+Markview can be installed via your favourite `package manager`.
### 💤 Lazy.nvim
-For `plugins.lua` or `lazy.lua` users.
+>[!CAUTION]
+> It is not recommended to lazy-load this plugin as it does that by default.
+
+For `lazy.lua` users.
```lua
{
"OXY2DEV/markview.nvim",
- ft = "markdown",
+ lazy = false, -- Recommended
+ -- ft = "markdown" -- If you decide to lazy-load anyway
dependencies = {
- -- You may not need this if you don't lazy load
+ -- You will not need this if you installed the
+ -- parsers manually
-- Or if the parsers are in your $RUNTIMEPATH
"nvim-treesitter/nvim-treesitter",
"nvim-tree/nvim-web-devicons"
- },
+ }
}
```
-For `plugins/markview.lua` users
+For `plugins/markview.lua` users.
```lua
return {
"OXY2DEV/markview.nvim",
- ft = "markdown",
+ lazy = false, -- Recommended
+ -- ft = "markdown" -- If you decide to lazy-load anyway
dependencies = {
- -- You may not need this if you don't lazy load
+ -- You will not need this if you installed the
+ -- parsers manually
-- Or if the parsers are in your $RUNTIMEPATH
"nvim-treesitter/nvim-treesitter",
"nvim-tree/nvim-web-devicons"
- },
+ }
}
```
@@ -102,76 +110,209 @@ MiniDeps.add({
})
```
-### 🤔 Others
+### 🌒 Rocks.nvim
+
+You can install the plugin by running the following command.
+
+```vim
+:Rocks install markview.nvim
+```
-The installation process for any other plugin manager(s) is the same.
+### 👾 Github releases
-If your plugin manager doesn't support `dependencies` then you can always load the plugins in the right order.
+You can also download one of the [releases](https://github.com/OXY2DEV/markview.nvim/releases/tag/v1.0.0).
+
+### 🛸 Testing
+
+If you don't mind a slightly `unstable` version of the plugin then you can use the [dev branch](https://github.com/OXY2DEV/markview.nvim/tree/dev).
+
+## 🌇 Commands
+
+Markview comes with a single command.
```vim
-Plug "nvim-treesitter/nvim-treesitter"
-Plug "nvim-tree/nvim-web-devicons"
+:Markview
+```
+
+It has the following `sub-commands`,
+
+- toggleAll, Toggles the plugin. Will set all **attached buffers** state to the plugin state.
+- enableAll, Enables the plugin in all **attached buffers**. Will refresh the decorations if the plugin is already enabled.
+- disableAll, Disables the plugin in all **attached buffers**. Will try to remove any remaining decorations if the plugin is already disabled.
+- toggle {buffer}, Toggles the state of buffer.
+- enable {buffer}, Enables/Refreshes the plugin on a specific buffer.
+- disable {buffer}, Disables the plugin & clears decorations on a specific buffer.
+
-Plug "OXY2DEV/markview.nvim"
+## 🧭 Configuration
+
+You can use the `setup()` function to change how the plugin looks.
+
+```lua
+local markview = require("markview");
+local presets = require("markview.presets");
+
+markview.setup({
+ headings = presets.headings.glow_labels
+});
+
+vim.cmd("Markview enableAll");
```
-## 🧭 Setup
+This can also be used at runtime. So, you can hot-swap the config anytime you want!
+
+Go ahead try running it.
+
+---
+
+You can configure the plugin in 2 ways,
+
+### 📂 Presets
+
+Presets are an easy way to change the looks of some part of the plugin.
+
+Currently there are presets for the following items,
+
+- Headings
+- Tables
+
+You can find more on presets on the [wiki page]().
+
+### 🎨 Manual
+
+The plugin was created with the sole purpose of being **customisable**.
->[!NOTE]
-> This plugin does not use `setup()` to initialize. So, it is completely optional to call it.
+So, you can change everything to fit your needs.
-Configuration table for the `setup()` function is given below.
+A simple example is given below,
```lua
require("markview").setup({
- buf_ignore = { "nofile" },
- modes = { "n", "no" },
-
- options = {
- on_enable = {},
- on_disable = {}
- },
-
- block_quotes = {},
- checkboxes = {},
- code_blocks = {},
- headings = {},
- horizontal_rules = {},
- inline_codes = {},
- links = {},
- list_items = {},
- tables = {}
+ headings = {
+ enable = true,
+
+ heading_1 = {
+ style = "label",
+
+ padding_left = " ",
+ padding_right = " ",
+
+ hl = "MarkviewHeading1"
+ }
+ }
});
```
- For customisation related options check the [wiki pages](https://github.com/OXY2DEV/markview.nvim/wiki).
+You can check the [wiki](https://github.com/OXY2DEV/markview.nvim/wiki) to learn more about configuration.
+
+You can also check the [starter guide]() for some simple examples.
+
+## 🌃 highlight groups
+
+To make configuration easier `markview.nvim` comes with the following highlight groups.
+
+### 📦 Block quote
+
+Block quotes have the following highlight group by default,
+
+- MarkviewBlockQuoteDefault, also used by `Quote`.
+
+Various callouts/alerts use the following highlight groups,
+
+- MarkviewBlockQuoteOk, used by `Tip`, `Success`.
+- MarkviewBlockQuoteWarn, used by `Question`, `Custom`, `Warning`.
+- MarkviewBlockQuoteError, used by `Caution`, `Bug`, `Danger`, `Failure`.
+- MarkviewBlockQuoteNote, used by `Note`, `Todo`, `Abstract`.
+- MarkviewBlockQuoteSpecial, used `Important`, `Example`.
+
+### 🎯 Checkboxes
+
+Checkboxes use these highlight groups,
+
+- MarkviewCheckboxChecked, from `DiagnosticOk`.
+- MarkviewCheckboxUnhecked, from `DiagnosticError`.
+- MarkviewCheckboxPending, from `DiagnosticWarn`.
+
+### 💻 Code blocks & inline codes
+
+Code blocks use the following highlight group,
-## 🎹 Commands
+- MarkviewCode
->[!NOTE]
-> Commands are a test feature.
+Inline codes use the following highlight group,
-There is only a single command for now, `:Markview`.
+- MarkviewInlineCode
-When called without any arguments, it toggles the plugin.
+### 🔖 Headings
-Possible subcommands are,
+Headings are highlighted with the following groups,
-- `toggleAll`, toggles the plugin
-- `enableAll`, enables the plugin
-- `disableAll`, disables the plugin
-- `toggle`, toggles the plugin for the specified buffer(default is the current buffer)
-- `enable`, enables the plugin for the specified buffer(default is the current buffer)
-- `disable`, disables the plugin for the specified buffer(default is the current buffer)
+- MarkviewHeading1, from `DiagnosticVirtualTextOk`
+- MarkviewHeading2, from `DiagnosticVirtualTextHint`
+- MarkviewHeading3, from `DiagnosticVirtualTextInfo`
+- MarkviewHeading4, from `Special`
+- MarkviewHeading5, from `DiagnosticVirtualTextWarn`
+- MarkviewHeading6, from `DiagnosticVirtualTextError`
-## 👾 Showcases
+Signs are highlighted with the following groups,
->[!IMPORTANT]
-> Screenshots on a phone are very blurry(Yes, the plugin was made on my phone).
->
-> If you have screenshots of the plugin, you can submit them in the special issue. And yes, credit will be provided.
+- MarkviewHeading1Sign, from `DiagnosticOk`
+- MarkviewHeading2Sign, from `DiagnosticHint`
+- MarkviewHeading3Sign, from `DiagnosticInfo`
+- MarkviewHeading4Sign, from `Special`
+- MarkviewHeading5Sign, from `DiagnosticWarn`
+- MarkviewHeading6Sign, from `DiagnosticError`
-![showcase_1](./images/preview_1.png)
+### 📏 Horizontal rules
+
+Horizontal rules use the following highlight groups for the gradient.
+
+- MarkviewGradient1, from `Normal`.
+- MarkviewGradient2
+- MarkviewGradient3
+- MarkviewGradient4
+- MarkviewGradient5
+- MarkviewGradient6
+- MarkviewGradient7
+- MarkviewGradient8
+- MarkviewGradient9
+- MarkviewGradient10, from `Cursor`.
+
+### 🔗 Links
+
+Links use the following highlight groups,
+
+- MarkviewHyperlink, from `markdownLinkText`.
+- MarkviewImageLink, from `markdownLinkText`.
+- MarkviewEmail, from `@markup.link.url.markdown_inline`.
+
+### 📝 List items
+
+List items use the following highlight groups,
+
+- MarkviewListItemMinus, from `DiagnosticWarn`.
+- MarkviewListItemPlus, from `DiagnosticOk`.
+- MarkviewListItemStar, from `@comment.note`.
+
+### 📐 Tables
+
+Tables use the following highlight group for the border,
+
+- MarkviewTableBorder, from `Title`.
+
+For the column alignment markers these highlight groups are used,
+
+- MarkviewTableAlignLeft, from `Title`.
+- MarkviewTableAlignRight, from `Title`.
+- MarkviewTableAlignCenter, from `Title`.
+
+## ⭐ Plugin showcase
+
+![showcase_1](https://github.com/OXY2DEV/markview.nvim/blob/images/Submitted/sc_scottmckendry.png)
Taken by @scottmckendry
+
+
diff --git a/doc/markview.txt b/doc/markview.txt
new file mode 100644
index 0000000..d1515e4
--- /dev/null
+++ b/doc/markview.txt
@@ -0,0 +1,1333 @@
+*markview.nvim* An experimental markdown previewer for Neovim
+
+ Created by `OXY2DEV`
+
+==============================================================================
+Table of contents *markview.nvim-toc*
+
+Features ............................................ |markview.nvim-features|
+Requirements .................................... |markview.nvim-requirements|
+
+Installation .................................... |markview.nvim-installation|
+ 💤 Lazy.nvim ...................................... |markview.nvim-i-lazy|
+ 🦠 Mini.deps .................................. |markview.nvim-i-minideps|
+ 🌒 Rocks.nvim .................................... |markview.nvim-i-rocks|
+
+Highlight groups ......................................... |markview.nvim-hls|
+Commands ............................................ |markview.nvim-commands|
+
+Plugin configuration .................................. |markview.nvim-config|
+ Block quotes .............................. |markview.nvim-c-block_quotes|
+ Checkboxes .................................. |markview.nvim-c-checkboxes|
+ Code blocks ................................ |markview.nvim-c-code_blocks|
+ Headings ...................................... |markview.nvim-c-headings|
+ Horizontal rules ................................... |markview.nvim-c-hrs|
+ Inline codes .............................. |markview.nvim-c-inline_codes|
+ Links ............................................ |markview.nvim-c-links|
+ List items .................................. |markview.nvim-c-list_items|
+ Tables .......................................... |markview.nvim-c-tables|
+
+Helper functions ..................................... |markview.nvim-helpers|
+
+==============================================================================
+Features *markview.nvim-features*
+
+- Fully stylized preview of `markdown` documents! Currently supported elements
+ are,
+ * atx_headings(uses `#`) & setext_headings(uses `---` or `===`)
+ * inline codes
+ * code blocks
+ * block quotes
+ * list items(both ordered & unordered)
+ * tables
+ * hyperlinks, image links & email urls
+ * horizontal rules
+ * checkboxes
+- Fully customisable elements. From icons, highlight groups to concealments,
+ padding almost everything can be customised.
+- `Dynamically` generated highlight groups. Useful for colorschemes that don't
+ support various highlight groups.
+ Note: The plugin will respect highlight groups set by the colorschemes
+ when available.
+- `Hybrid-mode` for editing and previewing at the same time.
+- Commands to quickly toggle the plugin(globally or per buffer).
+
+And so much more!
+
+==============================================================================
+Requirements *markview.nvim-requirements*
+
+- Neovim version `0.10.0` or higher.
+- `Tree-sitter` parser for `markdown` & `markdown_inline`.
+- `nvim-web-devicons`
+- Optionally, a `tree-sitter` compatible colorscheme.
+
+==============================================================================
+Installation *markview.nvim-installation*
+
+`markview.nvim` can be installed via your favourite package manager.
+
+------------------------------------------------------------------------------
+💤 Lazy.nvim *markview.nvim-i-lazy*
+
+For `lazy.lua` users.
+>lua
+ {
+ "OXY2DEV/markview.nvim",
+ ft = "markdown",
+
+ dependencies = {
+ -- You may not need this if you don't lazy load
+ -- Or if the parsers are in your $RUNTIMEPATH
+ "nvim-treesitter/nvim-treesitter",
+
+ "nvim-tree/nvim-web-devicons"
+ },
+ }
+<
+For `plugins/markview.lua` users.
+>lua
+ return {
+ "OXY2DEV/markview.nvim",
+ ft = "markdown",
+
+ dependencies = {
+ -- You may not need this if you don't lazy load
+ -- Or if the parsers are in your $RUNTIMEPATH
+ "nvim-treesitter/nvim-treesitter",
+
+ "nvim-tree/nvim-web-devicons"
+ },
+ }
+<
+
+Note:
+It is NOT recommended to lazy load this plugin as it already does that.
+
+Warning:
+You will not be able to access help files without opening a markdown file
+if you choose to lazy load.
+
+------------------------------------------------------------------------------
+🦠 Mini.deps *markview.nvim-i-minideps*
+>lua
+ local MiniDeps = require("mini.deps");
+
+ MiniDeps.add({
+ source = "OXY2DEV/markview.nvim",
+
+ depends = {
+ -- You may not need this if you don't lazy load
+ -- Or if the parsers are in your $RUNTIMEPATH
+ "nvim-treesitter/nvim-treesitter",
+
+ "nvim-tree/nvim-web-devicons"
+ }
+ });
+<
+------------------------------------------------------------------------------
+🌒 Rocks.nvim *markview.nvim-i-rocks*
+
+`markview.nvim` can be installed using the following command.
+>vim
+ :Rocks install markview.nvim
+<
+------------------------------------------------------------------------------
+Others
+
+Installation process for other plugin managers are similar.
+>vim
+ Plug "nvim-treesitter/nvim-treesitter"
+ Plug "nvim-tree/nvim-web-devicons"
+
+ Plug "OXY2DEV/markview.nvim"
+<
+==============================================================================
+Highlight groups *markview.nvim-hls*
+
+Note:
+ The `$` are NOT part of the name.
+
+- $MarkviewHeading1$ $MarkviewHeading1Sign$
+ $MarkviewHeading2$ $MarkviewHeading2Sign$
+ $MarkviewHeading3$ $MarkviewHeading3Sign$
+ $MarkviewHeading4$ $MarkviewHeading4Sign$
+ $MarkviewHeading5$ $MarkviewHeading5Sign$
+ $MarkviewHeading6$ $MarkviewHeading6Sign$
+
+ Highlight groups for different heading levels. `atx_headings` &
+ `setext_headings` both uses them
+
+- $MarkviewBlockQuoteDefault$
+ $MarkviewBlockQuoteOk$
+ $MarkviewBlockQuoteWarn$
+ $MarkviewBlockQuoteError$
+ $MarkviewBlockQuoteNote$
+ $MarkviewBlockQuoteSpecial$
+
+ Highlight groups responsible for various block quotes, `callouts` &
+ `alerts`.
+
+- $MarkviewCode$
+
+ Highlight group for showing `code blocks` and `inline codes`.
+
+- $MarkviewCheckboxChecked$
+ $MarkviewCheckboxUnchecked$
+ $MarkviewCheckboxPending$
+
+ Highlight group for the different `checkbox` states.
+
+- $MarkviewListItemPlus$
+ $MarkviewListItemMinus$
+ $MarkviewListItemStar$
+
+ Highlight groups for `unordered lists`. The plugin doesn't add decorations
+ to ordered lists.
+
+- $MarkviewTableBorder$
+
+ Highlight group for the borders of `tables`.
+
+ $MarkviewTableAlignLeft$
+ $MarkviewTableAlignRight$
+ $MarkviewTableAlignCenter$
+
+ Highlight groups for the various `alignment indicators` on rows.
+
+- $MarkviewGradient1$
+ $MarkviewGradient2$
+ $MarkviewGradient2$
+ $MarkviewGradient3$
+ $MarkviewGradient4$
+ $MarkviewGradient5$
+ $MarkviewGradient6$
+ $MarkviewGradient7$
+ $MarkviewGradient8$
+ $MarkviewGradient9$
+ $MarkviewGradient10$
+
+ Highlight groups used by the `horizontal rules`.
+
+==============================================================================
+Commands *markview.nvim-commands*
+
+Markview comes with the following command,
+>vim
+ :Markview
+<
+When used without any arguments it `toggles` the plugin state.
+
+It comes with the following sub-commands,
+
+- toggleAll
+
+ Toggles the plugin state. This will set ALL attached buffers to the same
+ state.
+
+- enableAll
+
+ Enables the plugin in all attached buffers. If the plugin is already enabled
+ then it will redraw everything.
+
+- disableAll
+
+ Disables the plugin in all attached buffers. If the plugin is already
+ diaable it will clear any remaining decorations.
+
+Note:
+When the {buffer} isn't provided these commands will run on the current
+buffer.
+
+- toggle {buffer}
+
+ Toggles the state of a buffer. Used for disabling the plugin on a specific
+ buffer.
+
+- enable {buffer}
+
+ Enables the plugin on a buffer. Redraws decorations if it's already enabled
+ in that buffer.
+
+- disable {buffer}
+
+ Disables the plugin on a specific buffer. Removes decorations if it's
+ already disabled in that buffer.
+
+------------------------------------------------------------------------------
+
+==============================================================================
+Plugin configuration *markview.nvim-config*
+
+The plugin can be configured via the `setup()` function.
+>lua
+ local presets = require("markview.presets");
+
+ require("markview").setup({
+ headings = presets.headings.glow_labels
+ });
+<
+
+The setup function comes with the following options,
+
+- modea `string[]`
+
+ A list of |vim-modes| where the preview will be shown. Default is,
+>lua
+ modes = { "n", "no" }
+<
+- hybrid_modes `string[] or nil`
+
+ A list of |vim-modes| where the text under the cursor is shown as raw text
+ without any decorations.
+
+ Default is nil.
+>lua
+ hybrid_modes = nil
+<
+- buf_ignore `string[] or nil`
+
+ A list of |'buftype'|s where the plugin will be disabled. Default is,
+>lua
+ buf_ignore = { "nofile" }
+<
+- callbacks
+ {
+ on_enable: `function or nil`,
+ on_disable: `function or nil`,
+
+ on_mode_change: `function or nil`
+ }
+
+ A table containing `callbacks` that will be run by the plugin on specific
+ events. See |markview.nvim-callbacks| for more info.
+
+ Example usage,
+>lua
+ callbacks = {
+ on_enable = function (_, win)
+ vim.wo[win].cursorline = false;
+ end
+ }
+<
+- headings `table or nil`
+
+ A table containing configuration for various `headings`. See
+ |markview.nvim-c-headings| for more info.
+
+ Example usage,
+>lua
+ headings = {
+ enable = false
+ }
+<
+- code_blocks `table or nil`
+
+ A table containing configuration for the `fenced code blocks`. See
+ |markview.nvim-c-code_blocks| for more info.
+
+ Example usage,
+>lua
+ code_blocks = {
+ enable = false
+ }
+<
+- inline_codes `table or nil`
+
+ A table containing configuration for the `inline codes`. See
+ |markview.nvim-c-inline_codes| for more info.
+
+ Example usage,
+>lua
+ inline_codes = {
+ enable = false
+ }
+<
+- block_quotes `table or nil`
+
+ A table containing configuration for the `block quotes`, `alerts` and
+ `callouts`. See |markview.nvim-c-block_quotes| for more info.
+
+ Example usage,
+>lua
+ block_quotes = {
+ enable = false
+ }
+<
+- horizontal_rules `table or nil`
+
+ A table containing configuration for the `horizontal rules`. See
+ |markview.nvim-c-hrs| for more info.
+
+ Example usage,
+>lua
+ horizontal_rules = {
+ enable = false
+ }
+<
+- links `table or nil`
+
+ A table containing configuration for various `links`. See
+ |markview.nvim-c-links| for more info.
+
+ Example usage,
+>lua
+ links = {
+ enable = false
+ }
+<
+- list_items `table or nil`
+
+ A table containing configuration for various `list items`. See
+ |markview.nvim-c-list_items| for more info.
+
+ Example usage,
+>lua
+ list_items = {
+ enable = false
+ }
+<
+- checkboxes `table or nil`
+
+ A table containing configuration for various `checkboxes`. See
+ |markview.nvim-c-checkboxes| for more info.
+
+ Example usage,
+>lua
+ checkboxes = {
+ enable = false
+ }
+<
+- tables `table or nil`
+
+ A table containing configuration for the `tables`. See
+ |markview.nvim-c-tables| for more info.
+
+ Example usage,
+>lua
+ tables = {
+ enable = false
+ }
+<
+------------------------------------------------------------------------------
+
+------------------------------------------------------------------------------
+Block quote *markview.nvim-c-block_quotes*
+
+Allows changing how block quotes, callouts & alerts.
+>lua
+ block_quotes = {
+ enable = true,
+
+ default = {
+ border = "▋",
+ border_hl = "MarkviewBlockQuoteDefault"
+ },
+
+ callouts = {
+ {
+ match_string = "ABSTRACT"
+ callout_preview = " Abstract",
+ callout_preview_hl = "MarkviewBlockQuoteNote",
+
+ custom_title = true,
+ custom_icon = " ",
+
+ border = "▋",
+ border_hl = "MarkviewBlockQuoteDefault"
+ }
+ }
+ }
+<
+enable ~
+ `boolean or nil`
+The `enable` option is used to disable the rendering of block quotes, callouts
+& alerts.
+
+default ~
+ `table`
+Configuration for block quotes and unknown callouts/alerts.
+
+It comes with the following properties,
+
+border ~
+ `string`
+A string to use as the border. Preferablly a single character.
+
+border_hl
+ `string or nil`
+Highlight group for the default border.
+
+------------------------------------------------------------------------------
+Checkboxes *markview.nvim-c-checkboxes*
+
+Configuration table for various checkbox states.
+>lua
+ checkboxes = {
+ enable = true,
+
+ checked = {
+ text = "✔",
+ hl = "MarkviewCheckboxChecked"
+ },
+ unchecked = {},
+ pending = {}
+ }
+<
+enable ~
+ `boolean or nil`
+The `enable` option is used to disable the rendering of checkboxes.
+
+checked ~
+ `table or nil`
+Configuration table for checked checkboxes.
+
+unchecked ~
+ `table or nil`
+Configuration table for unchecked checkboxes.
+
+pending ~
+ `table or nil`
+Configuration table for pending checkboxes.
+
+------------------------------------------------------------------------------
+Code blocks *markview.nvim-c-code_blocks*
+
+Allows changing how code_blocks are shown.
+>lua
+ headings = {
+ enable = true,
+ style = "minimal",
+
+ position = "minimal",
+ min_width = 60,
+ pad_amount = 3,
+ pad_char = " ",
+
+ language_names = {
+ "cpp", "c++",
+ "py", "python"
+ },
+
+ hl = "MarkviewCode",
+
+ sign = true,
+ sign_hl = nil
+ }
+<
+enable ~
+ `boolean or nil`
+The `enable` option is used to disable the rendering of headings entirely.
+
+style ~
+ `string`
+The rendering style of code blocks.
+
+ - simple
+
+ The lines within the code blocks are highlighted.
+
+ - minimal
+
+ Adds padding to the code block and surronds the block in a rectangle.
+
+ - language
+
+ Like minimal but adds icons, signs and language string to the blocks.
+
+position ~
+Only for the `minimal`, `language` styles.
+ `string or nil`
+The {virt_text_pos} of the top & bottom border of the code block. Default is
+`inline`.
+
+min_width ~
+Only for the `minimal`, `language` styles.
+ `number`
+The minimum width of the code block. This is without counting the
+`pad_amount`.
+
+pad_amount ~
+Only for the `minimal`, `language` styles.
+ `number`
+The number of `pad_char` to add before and after the lines of the code block.
+
+pad_char ~
+Only for the `minimal`, `language` styles.
+ `string`
+The text used as padding for the code blocks.
+
+language_names ~
+ `table or nil`
+
+A list of `tuples` containing a `match` & a `replacement`. Useful when you
+want to see `c++` instead of `cpp`.
+
+hl ~
+ `string`
+Highlight group for the code block.
+
+sign ~
+ `boolean or nil`
+When `true`, icons are shown in the |'signcolumn'| for code blocks
+
+sign_hl ~
+ `string or nil`
+A custom highlight group for the `signs`. When nil, the highlight group
+provided by `nvim-web-devicons` is used.
+
+------------------------------------------------------------------------------
+Headings *markview.nvim-c-headings*
+
+Allows changing how headings are shown.
+>lua
+ headings = {
+ enable = true,
+ shift_width = 3,
+
+ heading_1 = {},
+ heading_2 = {},
+ heading_3 = {},
+ heading_4 = {},
+ heading_5 = {},
+ heading_6 = {},
+
+ setext_1 = {},
+ setext_2 = {},
+ }
+<
+enable ~
+ `boolean or nil`
+The `enable` option is used to disable the rendering of headings entirely.
+
+shift_width ~
+Only for the `simple`, `icon` styles.
+ `number or nil`
+Number of `shift_char` to add per level of the headings.
+
+heading_<1-6> ~
+ `table or nil`
+`heading_1` to `heading_6` are used for styling atx_headings. They all have
+the following properties.
+
+style ~
+ `string`
+`atx_headings` support the following styles,
+
+ - simple
+
+ Adds simple background to the headings.
+
+ - label
+
+ Adds padding, icons, corner text, sign etc. `statusline`-like parts
+ around the heading text.
+
+ - icon
+
+ Adds simple icons to the headings. Also hides the `#` of the heading.
+
+NOTE:
+These styles are EXCLUSIVE to `atx_headings` and will not work with
+`setext_headings`.
+
+`setext_headings` support the following styles.
+
+ - simple
+
+ Adds simple background to the headings.
+
+ - github
+
+ Adds an icon before the heading text and a line under the heading text.
+ Kinda like how headings are shown in GitHub.
+
+shift_char ~
+ `string or nil`
+Thw character to use as padding before the heading.
+
+------------------------------------------------------------------------------
+
+corner_left ~
+Only for the `label` style.
+ `string or nil`
+Only useful when adding different colored sections before the left padding.
+
+padding_left ~
+Only for the `label` style.
+ `string or nil`
+The text to use as padding before the heading.
+
+icon ~
+Only for the `label` style.
+ `string or nil`
+The text to use as an icon before the heading text.
+
+padding_right ~
+Only for the `label` style.
+ `string or nil`
+The text to use as padding after the heading.
+
+corner_right ~
+Only for the `label` style.
+ `string or nil`
+Only useful when adding different colored sections after the right padding.
+
+
+
+hl ~
+ `string or nil`
+Highlight group to be applied to the entire range of the node. It is added as
+the `line_hl_group` when the style is `icon`.
+
+It is used as the default value for the following properties.
+
+corner_left_hl ~
+Only for the `label` style.
+ `string or nil`
+Highlight group for the left corner.
+
+padding_left_hl ~
+Only for the `label` style.
+ `string or nil`
+Highlight group for the left padding.
+
+icon_hl ~
+Only for the `label`, `icon` styles.
+ `string or nil`
+Highlight group for icon.
+
+text_hl ~
+Only for the `label`, `icon` styles.
+ `string or nil`
+Highlight group for heading text.
+
+padding_right_hl ~
+Only for the `label` style.
+ `string or nil`
+Highlight group for the left padding.
+
+corner_right_hl ~
+Only for the `label` style.
+ `string or nil`
+Highlight group for the left corner.
+
+------------------------------------------------------------------------------
+Horizontal rules *markview.nvim-c-hrs*
+
+Configuration table for line breaks or horizontal rules.
+>lua
+horizontal_rules = {
+ enable = true,
+
+ parts = {
+ {
+ type = "repeating",
+
+ text = "─",
+ hl = { "MarkviewGradient1", "MarkviewGradient2" },
+ direction = "left",
+
+ repeat_amount = function ()
+ return vim.o.columns - 3;
+ end
+ },
+ {
+ type = "text",
+ text = " • ",
+ hl = "MarkviewGradient5"
+ }
+ }
+ }
+<
+enable ~
+ `boolean or nil`
+The `enable` option is used to disable the rendering of line breaks/horizontal
+rules.
+
+parts ~
+ `table`
+A list of parts to create a horizontal rule. There are 2 types of parts
+available,
+
+- repeating
+
+ Repeats the provided text by a number of time.
+
+ - text
+
+ Renders some raw text to the screen.
+
+------------------------------------------------------------------------------
+
+Parts: repeating ~
+ *markview.nvim-hr-repeating*
+Repeats a text a specific number of times. It has the following properties,
+
+type ~
+ `string`
+The type of a part. In this case it's value would be `repeating`.
+
+text ~
+ `string`
+The text to repeat.
+
+hl ~
+ `table or nil`
+A list of colors to use for the part. The `direction` property changes where
+the color is applied in the final string.
+
+direction ~
+ `string or nil`
+The side of the final string where the `hl` would be applied. Possible values
+are,
+ - left
+ - right
+
+Default is `left`.
+
+repeat_amount ~
+ `function or number`
+The number of times to repeat `text`. If the value is a `function` then the
+returned value is used.
+
+------------------------------------------------------------------------------
+
+Parts: text ~
+ *markview.nvim-hr-text*
+Shows some text in the horizontal rule. It has the following properties,
+
+text ~
+ `string`
+The text to show.
+
+hl ~
+ `string or nil`
+Highlight group for coloring `text`
+
+------------------------------------------------------------------------------
+Inline codes *markview.nvim-c-inline_codes*
+
+Configuration table for `inline codes`/codespans.
+
+enable ~
+ `boolean or nil`
+The `enable` option is used to disable the rendering of inline codes.
+
+corner_left ~
+ `string or nil`
+Only useful when adding different colored sections before the left padding.
+
+padding_left ~
+ `string or nil`
+The text to use as padding before the heading.
+
+icon ~
+ `string or nil`
+The text to use as an icon before the heading text.
+
+padding_right ~
+ `string or nil`
+The text to use as padding after the heading.
+
+corner_right ~
+ `string or nil`
+Only useful when adding different colored sections after the right padding.
+
+
+
+hl ~
+ `string or nil`
+Highlight group to be applied to the entire range of the node.
+
+It is used as the default value for the following properties.
+
+corner_left_hl ~
+ `string or nil`
+Highlight group for the left corner.
+
+padding_left_hl ~
+ `string or nil`
+Highlight group for the left padding.
+
+icon_hl ~
+ `string or nil`
+Highlight group for icon.
+
+text_hl ~
+ `string or nil`
+Highlight group for heading text.
+
+padding_right_hl ~
+ `string or nil`
+Highlight group for the left padding.
+
+corner_right_hl ~
+ `string or nil`
+Highlight group for the left corner.
+
+------------------------------------------------------------------------------
+Links *markview.nvim-c-links*
+
+Configuration tables for various types of links.
+>lua
+ links = {
+ enable = true,
+
+ hyperlinks = {
+ icon = "H",
+ hl = "MarkviewHyperlink"
+ },
+ images = {},
+ emails = {}
+ }
+<
+enable ~
+ `boolean or nil`
+The `enable` option is used to disable the rendering of links.
+
+hyperlinks ~
+ `table or nil`
+Configuration table for regular links(links using `[]()`).
+
+images ~
+ `table or nil`
+Configuration table for image links(links using `![]()`).
+
+emails ~
+ `table or nil`
+Configuration table for email urls(links using `<>`).
+
+------------------------------------------------------------------------------
+
+All the options(other than `enable`) have these properties.
+
+corner_left ~
+ `string or nil`
+Only useful when adding different colored sections before the left padding.
+
+padding_left ~
+ `string or nil`
+The text to use as padding before the heading.
+
+icon ~
+ `string or nil`
+The text to use as an icon before the heading text.
+
+padding_right ~
+ `string or nil`
+The text to use as padding after the heading.
+
+corner_right ~
+ `string or nil`
+Only useful when adding different colored sections after the right padding.
+
+
+
+hl ~
+ `string or nil`
+Highlight group to be applied to the entire range of the node.
+
+It is used as the default value for the following properties.
+
+corner_left_hl ~
+ `string or nil`
+Highlight group for the left corner.
+
+padding_left_hl ~
+ `string or nil`
+Highlight group for the left padding.
+
+icon_hl ~
+ `string or nil`
+Highlight group for icon.
+
+text_hl ~
+ `string or nil`
+Highlight group for heading text.
+
+padding_right_hl ~
+ `string or nil`
+Highlight group for the left padding.
+
+corner_right_hl ~
+ `string or nil`
+Highlight group for the left corner.
+
+------------------------------------------------------------------------------
+List items *markview.nvim-c-list_items*
+
+Configuration table for various list items.
+>lua
+ list_items = {
+ enable = true,
+
+ marker_plus = {
+ add_padding = true,
+
+ text = "•",
+ hl = "MarkviewListItemPlus"
+ }
+ }
+<
+Note: List items nodes have different start and end ranges for different list
+level. This can cause issues when you do a lot of nesting inside lists.
+
+It is not recommended to use decorations that can cause items to go out of
+place.
+
+enable ~
+ `boolean or nil`
+The `enable` option is used to disable the rendering of list items.
+
+marker_plus ~
+ `table or nil`
+Configuration table for lists starting with `+`.
+
+marker_minus ~
+ `table or nil`
+Configuration table for lists starting with `-`.
+
+marker_star ~
+ `table or nil`
+Configuration table for lists starting with `*`.
+
+------------------------------------------------------------------------------
+
+All the options(other than `enable`) have these properties.
+
+text ~
+ `string or nil`
+The text to use as the marker. It will `conceal` the oroginal marker and
+replace it with this text.
+
+hl ~
+ `string or nil`
+Highlight group for `text`.
+
+------------------------------------------------------------------------------
+
+All the options(other than `enable`) have these properties.
+
+text ~
+ `string or nil`
+The text to use as the checkbox. It will `conceal` the original marker and
+replace it with this text.
+
+hl ~
+ `string or nil`
+Highlight group for `text`.
+
+------------------------------------------------------------------------------
+Tables *markview.nvim-c-tables*
+
+Configuration table for tables.
+>lua
+ tables = {
+ enable = true,
+
+ text = {},
+ hl = {},
+
+ use_virt_lines = false
+ }
+<
+enable ~
+ `boolean or nil`
+The `enable` option is used to disable the rendering of tables.
+
+use_virt_lines ~
+ `boolean or nil`
+When `true`, the top & bottom borders are made of `virtual lines`. Useful if
+you don't like having gaps between tables.
+
+text ~
+ `table`
+A list of `12` string used to create the table.
+>txt
+ Main borders Row & column separtor
+ ------------------- ---------------------
+ "╭", "─", "╮", "┬",
+ "├", "│", "┤", "┼",
+ "╰", "─", "╯", "┴",
+
+ Alignment markers
+ -----------------------------------------
+ "╼", "╾", "╴", "╶"
+ Left Right Center
+<
+
+hl ~
+ `table or nil`
+A list of `12` highlight group for the strings in `text`.
+
+------------------------------------------------------------------------------
+Helper functions *markview.nvim-helpers*
+
+The plugin comes with a few helper functions to easily create Dynamic
+|highlight-groups|.
+
+Color related helper functions can be used either through `markview.colors` or
+by requiring the file Directly.
+>lua
+ local markview = require("markview");
+ vim.print(markview.colors.get_hl_value(0, "Special", "fg"));
+<
+------------------------------------------------------------------------------
+
+ *markview.nvim-h-lerp*
+colors.lerp({x}: number, {y}: number, {t}: number) -> number
+
+ The mising `math.lerp()` function. Does `linear interpolation` between
+ x & y.
+
+ Parameters: ~
+
+ • {x} The start value.
+ • {y} The stop/end value.
+ • {t} A float between 0.00 & 1.00 to interpolate to.
+
+ Result: ~
+
+ • {number} The interpolated value.
+
+ *markview.nvim-h-clamp*
+colors.clamp({value}: number, {min}: number, {max}: number) -> number
+
+ The mising `math.clamp()` function. Clamps a value between min & max.
+
+ Parameters: ~
+
+ • {value} The value to clamp.
+ • {min} Minimum value.
+ • {max} Maximum value.
+
+ Result: ~
+
+ • {number} The clamped value.
+
+ *markview.nvim-h-name_to_hex*
+colors.name_to_hex({name}: string) -> string
+
+ Turns |gui-colors| into heaxadecimal values.
+
+ Used for converting |'guifg'|, |'guibg'| & |'guisp'| values provided
+ by |nvim_get_hl()| into human readable colors.
+
+ Parameters: ~
+
+ • {name} Name of the color.
+
+ Result: ~
+
+ • {string} The converted hexadecimal color.
+
+ *markview.nvim-h-name_to_rgb*
+colors.name_to_rgb({name}: string) -> { r: number, g: number, b: number }
+
+ Turns |gui-colors| into tables containing r, g, b values.
+
+ Used for converting |'guifg'|, |'guibg'| & |'guisp'| values provided
+ by |nvim_get_hl()| into human readable colors.
+
+ Parameters: ~
+
+ • {name} Name of the color.
+
+ Result: ~
+
+ • {table} A table containing the r, g, b values.
+
+ *markview.nvim-h-num_to_hex*
+colors.num_to_hex({num}: number) -> string
+
+ Converts numbers into hexadecimal string. A `#` is added before the
+ output string.
+
+ Used for converting |'guifg'|, |'guibg'| & |'guisp'| values provided
+ by |nvim_get_hl()| into human readable colors.
+
+ Parameters: ~
+
+ • {num} Number to convert.
+
+ Result: ~
+
+ • {string} The converted hexadecimal color.
+
+ *markview.nvim-h-num_to_rgb*
+colors.num_to_rgb({num}: number) -> { r: number, g: number, b: number }
+
+ Sperates color numbers into r, g, b values.
+
+ Rarely used for translating outputs of |nvim_get_hl()|.
+
+ Parameters: ~
+
+ • {num} Number to seperate.
+
+ Result: ~
+
+ • {table} Table containing r, g, b values.
+
+ *markview.nvim-h-hex_to_rgb*
+colors.hex_to_rgb({str}: string) -> { r: number, g: number, b: number }
+
+ Seperates hex color codes to r, g, b colors.
+
+ Supports codes with or without `#` in front of them. Also supports
+ `3-digit` & `6-digit` hex color codes.
+
+ Parameters: ~
+
+ • {str} Hexadecimal string to seperate.
+
+ Result: ~
+
+ • {table} Table containing r, g, b values.
+
+ *markview.nvim-h-rgb_to_hex*
+colors.rgb_to_hex({ {r}: number, {g}: number, {b}: number }) -> string
+
+ Turns table containing r, g, b values into valid hex color codes.
+
+ Used internally for transforming color values.
+
+ Parameters: ~
+
+ • {tbl} A table containing r, g, b values.
+
+ Result: ~
+
+ • {table} 6-digit hex color code.
+
+ *markview.nvim-h-get_hl_value*
+colors.get_hl_value({ns_id}: number, {hl_group}: string, {value}: string)
+ -> any
+
+ A wrapper function for |nvim_get_hl()|.
+
+ Gets {value} of {hl_group} in the provided {ns_id}. If {value} is `fg`,
+ `bg` or `sp` the returned value will be a table containing the r, g, b
+ values. Otherwise the value is directly returned.
+
+ Parameters: ~
+
+ • {ns_id} Namespace ID. See |namespace| for more information.
+ • {hl_group} Highlight group name.
+ • {value} The value to return.
+
+ Result: ~
+
+ • {any} Any of the value returned by |nvim_get_hl()|.
+
+ *markview.nvim-h-create_gradient*
+colors.create_gradient(
+ {name_prefix}: string,
+
+ {from}: color,
+ {to}: color,
+
+ {steps}: number,
+ {mode}: string
+) -> { {group_name}: string, {value}: table }
+
+ Creates a list of `highlight groups` for the {highlight_groups} option.
+
+ A 2-stop gradient is generated between {from} & {to}. The value of
+ {from} & {to} can either be a number, string or a table with r, g, b
+ values.
+
+ The {mode} can be used to make the gradient into the background color or
+ the foreground color or both.
+
+ Parameters: ~
+
+ • {name_prefix} The prefix to add before each of the {group_name}.
+
+ E.g. setting the {name_prefix} to "Gradient" will
+ result in group names being "Gradient" where
+ "" is the step number.
+
+ • {from} The start color of the gradient. Can be a number,
+ a string or a table. It will be converted to a
+ table containing r, g, b values.
+ • {to} The stop color of the gradient. Works like {from}.
+
+ • {steps} Number of steps in the gradient(including the start
+ and stop colors).
+ • {mode} The color mode of the gradient. Possible values are,
+ • bg: Applies the color to the background.
+ • fg: Applies the color to the foreground.
+ • both: Does all of the above.
+
+ Result: ~
+
+ • {table} A list of tables containing a {group_name} and a
+ {value}. Mainly for use in {highlight_groups}.
+
+ *markview.nvim-h-mix*
+colors.mix(
+ {color_1}: color, {color_2}: color,
+ {per_1}: number, {per_2}: number
+) -> string
+
+ Mixes {color_1}, {color_2} to create a new color.
+
+ The value of {color_1} & {color_2} can either be a number, string
+ or a table with r, g, b values.
+
+ The {per_1} & {per_2} are floats between 0 & 1. They are used as % values
+ of the r, g, b values of the corresponding color. They are then added
+ together to make the new color.
+
+ Parameters: ~
+
+ • {color_1} The first color to mix. Can be a number,
+ a string or a table. It will be converted to a
+ table containing r, g, b values.
+ • {color_2} The stop color of the gradient. Works like
+ {color_1}.
+
+ • {per_1} The % of {color_1} to mix.
+ • {per_2} The % of {color_2} to mix.
+
+ Result: ~
+
+ • {string} The hex color code of the resulting color.
+
+ *markview.nvim-h-get_brightness*
+colors.get_brightness({color}: color) -> number
+
+ Gets the `luminosity` value of the color. Supports hexadecimal numbers,
+ color names, tables containing r, g, b values.
+
+ Parameters: ~
+
+ • {color} The first color to mix. Can be a number,
+ a string or a table. It will be converted to a
+ table containing r, g, b values.
+
+ Result: ~
+
+ • {number} Luminosity value between 0 & 1.
+
+ *markview.nvim-h-brightest*
+colors.brightest({list}: color[]) -> string
+
+ Gets the brightest color from the provided list of colors.
+
+ Parameters: ~
+ • {list} A list of colors. Can contain hexadecimal numbers, numbers,
+ color names & tables with r, g, b values.
+
+ Result: ~
+
+ • {string} The brightest color's hex color code.
+
+ *markview.nvim-h-get*
+colors.get({list}: any[]) -> any
+
+ Gets the first `non-nil` value from a list(with empty holes) of values.
+
+vim:ft=help:bt=help:textwidth=78:ts=4:spell:
diff --git a/doc/tags b/doc/tags
new file mode 100644
index 0000000..039040e
--- /dev/null
+++ b/doc/tags
@@ -0,0 +1,37 @@
+markview.nvim markview.txt /*markview.nvim*
+markview.nvim-c-block_quotes markview.txt /*markview.nvim-c-block_quotes*
+markview.nvim-c-checkboxes markview.txt /*markview.nvim-c-checkboxes*
+markview.nvim-c-code_blocks markview.txt /*markview.nvim-c-code_blocks*
+markview.nvim-c-headings markview.txt /*markview.nvim-c-headings*
+markview.nvim-c-hrs markview.txt /*markview.nvim-c-hrs*
+markview.nvim-c-inline_codes markview.txt /*markview.nvim-c-inline_codes*
+markview.nvim-c-links markview.txt /*markview.nvim-c-links*
+markview.nvim-c-list_items markview.txt /*markview.nvim-c-list_items*
+markview.nvim-c-tables markview.txt /*markview.nvim-c-tables*
+markview.nvim-commands markview.txt /*markview.nvim-commands*
+markview.nvim-config markview.txt /*markview.nvim-config*
+markview.nvim-features markview.txt /*markview.nvim-features*
+markview.nvim-h-brightest markview.txt /*markview.nvim-h-brightest*
+markview.nvim-h-clamp markview.txt /*markview.nvim-h-clamp*
+markview.nvim-h-create_gradient markview.txt /*markview.nvim-h-create_gradient*
+markview.nvim-h-get markview.txt /*markview.nvim-h-get*
+markview.nvim-h-get_brightness markview.txt /*markview.nvim-h-get_brightness*
+markview.nvim-h-get_hl_value markview.txt /*markview.nvim-h-get_hl_value*
+markview.nvim-h-hex_to_rgb markview.txt /*markview.nvim-h-hex_to_rgb*
+markview.nvim-h-lerp markview.txt /*markview.nvim-h-lerp*
+markview.nvim-h-mix markview.txt /*markview.nvim-h-mix*
+markview.nvim-h-name_to_hex markview.txt /*markview.nvim-h-name_to_hex*
+markview.nvim-h-name_to_rgb markview.txt /*markview.nvim-h-name_to_rgb*
+markview.nvim-h-num_to_hex markview.txt /*markview.nvim-h-num_to_hex*
+markview.nvim-h-num_to_rgb markview.txt /*markview.nvim-h-num_to_rgb*
+markview.nvim-h-rgb_to_hex markview.txt /*markview.nvim-h-rgb_to_hex*
+markview.nvim-helpers markview.txt /*markview.nvim-helpers*
+markview.nvim-hls markview.txt /*markview.nvim-hls*
+markview.nvim-hr-repeating markview.txt /*markview.nvim-hr-repeating*
+markview.nvim-hr-text markview.txt /*markview.nvim-hr-text*
+markview.nvim-i-lazy markview.txt /*markview.nvim-i-lazy*
+markview.nvim-i-minideps markview.txt /*markview.nvim-i-minideps*
+markview.nvim-i-rocks markview.txt /*markview.nvim-i-rocks*
+markview.nvim-installation markview.txt /*markview.nvim-installation*
+markview.nvim-requirements markview.txt /*markview.nvim-requirements*
+markview.nvim-toc markview.txt /*markview.nvim-toc*
diff --git a/ftplugin/markdown.lua b/ftplugin/markdown.lua
index abc2d98..a1de838 100644
--- a/ftplugin/markdown.lua
+++ b/ftplugin/markdown.lua
@@ -3,19 +3,21 @@ local utils = require("markview.utils");
local ts_available, treesitter_parsers = pcall(require, "nvim-treesitter.parsers");
local function parser_installed(parser)
- return (ts_available and treesitter_parsers.has_parser(parser)) or
- (vim.treesitter.query.get(parser, "highlights"))
+ return (ts_available and treesitter_parsers.has_parser(parser)) or pcall(vim.treesitter.query.get, parser, "highlights")
end
-- Check for requirements
if vim.fn.has("nvim-0.10") == 0 then
- vim.print("[ markview.nvim ] : Thie plugin is only available on version 0.10.0 and higher!");
+ vim.notify("[ markview.nvim ] : Thie plugin is only available on version 0.10.0 and higher!", vim.log.levels.WARN);
return;
elseif not parser_installed("markdown") then
- vim.print("[ markview.nvim ] : Treesitter parser for 'markdown' wasn't found!");
+ vim.notify("[ markview.nvim ] : Treesitter parser for 'markdown' wasn't found!", vim.log.levels.WARN);
return;
elseif not parser_installed("markdown_inline") then
- vim.print("[ markview.nvim ] : Treesitter parser for 'markdown_inline' wasn't found!");
+ vim.notify("[ markview.nvim ] : Treesitter parser for 'markdown_inline' wasn't found!", vim.log.levels.WARN);
+ return;
+elseif not parser_installed("html") then
+ vim.notify("[ markview.nvim ] : Treesitter parser for 'html' wasn't found! It is required for basic html tag support.", vim.log.levels.WARN);
return;
end
@@ -23,12 +25,13 @@ if vim.islist(markview.configuration.buf_ignore) and vim.list_contains(markview.
return
end
-if vim.islist(markview.configuration.highlight_groups) then
+-- Don't add hls unless absolutely necessary
+if not markview.added_hls and vim.islist(markview.configuration.highlight_groups) then
markview.add_hls(markview.configuration.highlight_groups)
+ markview.added_hls = true;
end
local markview_augroup = vim.api.nvim_create_augroup("markview_buf_" .. vim.api.nvim_get_current_buf(), { clear = true });
-local options = markview.configuration.options;
vim.api.nvim_create_autocmd({ "BufWinEnter" }, {
buffer = vim.api.nvim_get_current_buf(),
@@ -44,30 +47,43 @@ vim.api.nvim_create_autocmd({ "BufWinEnter" }, {
end
if markview.state.enable == false then
+ -- Call the on_disable callback before exiting
+ if not markview.configuration.callbacks or not markview.configuration.callbacks.on_disable then
+ return;
+ end
+
+ for _, window in ipairs(windows) do
+ pcall(markview.configuration.callbacks.on_disable, buffer, window);
+ end
+
return;
end
if markview.state.buf_states[buffer] == false then
+ -- Call the on_disable callback before exiting
+ -- Even if only the buffer is disabled
+ if not markview.configuration.callbacks or not markview.configuration.callbacks.on_disable then
+ return;
+ end
+
+ for _, window in ipairs(windows) do
+ pcall(markview.configuration.callbacks.on_disable, buffer, window);
+ end
+
return;
end
markview.state.buf_states[buffer] = true;
- if vim.tbl_isempty(markview.global_options) then
- markview.global_options = {
- conceallevel = vim.o.conceallevel,
- concealcursor = vim.o.concealcursor
- }
- end
-
- local parsed_content = markview.parser.init(buffer);
+ local parsed_content = markview.parser.init(buffer, markview.configuration);
markview.renderer.clear(buffer);
markview.renderer.render(buffer, parsed_content, markview.configuration)
for _, window in ipairs(windows) do
- vim.wo[window].conceallevel = type(options.on_enable) == "table" and options.on_enable.conceallevel or 2;
- vim.wo[window].concealcursor = type(options.on_enable) == "table" and options.on_enable.concealcursor or "n";
+ if markview.configuration.callbacks and markview.configuration.callbacks.on_enable then
+ pcall(markview.configuration.callbacks.on_enable, buffer, window);
+ end
markview.keymaps.init(buffer, window, parsed_content, markview.configuration);
end
@@ -93,61 +109,112 @@ vim.api.nvim_create_autocmd({ "ModeChanged", "TextChanged" }, {
return;
end
- if vim.islist(markview.configuration.modes) and vim.list_contains(markview.configuration.modes, mode) then
- local parsed_content = markview.parser.init(buffer);
- local cursor = vim.api.nvim_win_get_cursor(0) or {1, 0};
+ -- Only on mode change
+ if event.event == "ModeChanged" then
+ -- Call the on_mode_change callback before exiting
+ if not markview.configuration.callbacks or not markview.configuration.callbacks.on_mode_change then
+ goto noCallbacks;
+ end
- local draw_start, draw_stop = utils.get_cursor_range(buffer, windows[1], markview.configuration);
+ for _, window in ipairs(windows) do
+ pcall(markview.configuration.callbacks.on_mode_change, buffer, window, mode);
+ end
+ end
+
+ ::noCallbacks::
+
+ if markview.configuration.modes and vim.list_contains(markview.configuration.modes, mode) then
+ local parsed_content = markview.parser.init(buffer, markview.configuration);
+ local parse_start, parse_stop = utils.get_cursor_range(buffer, windows[1]);
markview.renderer.clear(buffer);
- markview.renderer.render(buffer, parsed_content, markview.configuration, draw_start, draw_stop);
- if vim.list_contains(markview.configuration.modes, "i") and mode == "i" then
- local partial_contents = markview.parser.parse_range(buffer, draw_start, draw_stop);
+ local partial_contents = markview.parser.parse_range(event.buf, markview.configuration, parse_start, parse_stop);
+ local current_range = markview.renderer.get_content_range(partial_contents);
- markview.renderer.clear_partial_range(buffer, partial_contents);
- -- markview.renderer.render_deleted(event.buf, cursor, markview.configuration);
- -- markview.renderer.clear_under_cursor(buffer, cursor);
+ if markview.configuration.hybrid_modes and vim.list_contains(markview.configuration.hybrid_modes, mode) then
+ markview.renderer.render(buffer, parsed_content, markview.configuration, parse_start, parse_stop);
+ markview.renderer.clear_content_range(event.buf, partial_contents)
+ else
+ markview.renderer.render(buffer, parsed_content, markview.configuration);
end
- for _, window in ipairs(windows) do
- vim.wo[window].conceallevel = type(options.on_enable) == "table" and options.on_enable.conceallevel or 2;
- vim.wo[window].concealcursor = type(options.on_enable) == "table" and options.on_enable.concealcursor or "n";
+ -- Or else things won't render on first redraw from the other autocmd
+ markview.renderer.update_range(buffer, current_range);
+ for _, window in ipairs(windows) do
markview.keymaps.init(buffer, window, parsed_content, markview.configuration);
end
else
- for _, window in ipairs(windows) do
- vim.wo[window].conceallevel = type(options.on_disable) == "table" and options.on_disable.conceallevel or markview.global_options.conceallevel;
- vim.wo[window].concealcursor = type(options.on_disable) == "table" and options.on_disable.concealcursor or markview.global_options.concealcursor;
- end
-
+ -- Call an extra redraw to flush out screen updates
markview.renderer.clear(buffer);
+ vim.cmd("redraw!");
end
end
});
-if not vim.list_contains(markview.configuration.modes, "i") then
+if not markview.configuration.hybrid_modes then
return;
end
+local events = {}
local move_timer = vim.uv.new_timer();
-vim.api.nvim_create_autocmd({ "CursorMovedI" }, {
+if vim.list_contains(markview.configuration.hybrid_modes, "n") or vim.list_contains(markview.configuration.hybrid_modes, "v") then
+ table.insert(events, "CursorMoved");
+end
+
+if vim.list_contains(markview.configuration.hybrid_modes, "i") then
+ table.insert(events, "CursorMovedI");
+ table.insert(events, "TextChangedI"); -- For smoother experience when writing, potentially can cause bugs
+end
+
+vim.api.nvim_create_autocmd(events, {
buffer = vim.api.nvim_get_current_buf(),
group = markview_augroup,
callback = function (event)
+ if markview.state.enable == false then
+ move_timer:stop();
+ return;
+ end
+
+ if markview.state.buf_states[event.buf] == false then
+ move_timer:stop();
+ return;
+ end
+
move_timer:stop();
move_timer:start(100, 0, vim.schedule_wrap(function ()
- local prev_contents = markview.parser.parse_range(event.buf);
+ if not _G.__markview_render_ranges then
+ _G.__markview_render_ranges = {};
+ end
+
+ if not _G.__markview_render_ranges[event.buf] then
+ _G.__markview_render_ranges[event.buf] = {};
+ end
+
+ local windows = utils.find_attached_wins(event.buf);
+
+ local old_start, old_stop = _G.__markview_render_ranges[event.buf][1], _G.__markview_render_ranges[event.buf][2];
+ local parse_start, parse_stop = utils.get_cursor_range(event.buf, windows[1]);
+
+ local prev_contents = markview.parser.parse_range(event.buf, markview.configuration, old_start, old_stop);
+ local partial_contents = markview.parser.parse_range(event.buf, markview.configuration, parse_start, parse_stop);
+
+ local current_range = markview.renderer.get_content_range(partial_contents);
+
+ if _G.__markview_render_ranges[event.buf] and vim.deep_equal(_G.__markview_render_ranges[event.buf], current_range) then
+ markview.renderer.clear_content_range(event.buf, partial_contents)
+ return;
+ end
- local draw_start, draw_stop = utils.get_cursor_range(event.buf, 0, markview.configuration);
- local partial_contents = markview.parser.parse_range(event.buf, draw_start, draw_stop);
+ markview.renderer.clear_content_range(event.buf, partial_contents)
+ markview.renderer.clear_content_range(event.buf, prev_contents);
+ markview.renderer.clear(event.buf, parse_start, parse_stop);
- markview.renderer.clear_partial_range(event.buf, prev_contents);
- markview.renderer.render_partial(event.buf, prev_contents, markview.configuration, draw_start, draw_stop);
- markview.renderer.clear_partial_range(event.buf, partial_contents);
+ markview.renderer.render_in_range(event.buf, prev_contents, markview.configuration);
+ markview.renderer.update_range(event.buf, current_range);
end));
end
})
diff --git a/images/headings.jpg b/images/headings.jpg
deleted file mode 100644
index 4653213..0000000
Binary files a/images/headings.jpg and /dev/null differ
diff --git a/images/lists.jpg b/images/lists.jpg
deleted file mode 100644
index f05449c..0000000
Binary files a/images/lists.jpg and /dev/null differ
diff --git a/images/preview_1.png b/images/preview_1.png
deleted file mode 100644
index fb49d52..0000000
Binary files a/images/preview_1.png and /dev/null differ
diff --git a/images/tables.jpg b/images/tables.jpg
deleted file mode 100644
index cc135fb..0000000
Binary files a/images/tables.jpg and /dev/null differ
diff --git a/lua/definitions.lua b/lua/definitions.lua
index 4e57138..ff235f2 100644
--- a/lua/definitions.lua
+++ b/lua/definitions.lua
@@ -16,8 +16,11 @@
--- List of modes where the plugin will be active
---@field modes string[]?
---
---- Options for various plugins states
----@field options markview.config.options?
+--- List of modes where both raw & preview is shown
+---@field hybrid_modes string[]?
+---
+--- Callbacks for plugin states
+---@field callbacks markview.config.callbacks?
---
--- Table for heading configuration
---@field headings markview.render_config.headings?
@@ -59,8 +62,11 @@
--- List of modes where the plugin will be active
---@field modes string[]
---
+--- List of modes where both raw & preview is shown
+---@field hybrid_modes string[]?
+---
--- Options for various plugins states
----@field options markview.config.options
+---@field callbacks markview.config.callbacks
---
--- Table for heading configuration
---@field headings markview.render_config.headings
@@ -77,7 +83,7 @@
--- Table for hyperlink configuration
---@field links markview.render_config.links
---
---- Table for hyperlink configuration
+--- Table for inline code configuration
---@field inline_codes markview.render_config.inline_codes
---
--- Table for list item configuration
@@ -90,20 +96,14 @@
---@field tables markview.render_config.tables
---- Definition for the options
----@class markview.config.options
+--- Definition for the plugin callbacks
+---@class markview.config.callbacks
---
----@field on_enable markview.config.options.available
+---@field on_enable function?
---
----@field on_disable markview.config.options.available
-
---- Available options
----@class markview.config.options.available
----
---- Conceal level
----@field conceallevel number
+---@field on_disable function?
---
----@field concealcursor string?
+---@field on_mode_change function?
---------------------------------------------------------------
--- For rendering things
@@ -137,7 +137,7 @@
--- Used for highlighting the line when the style is "simple"
---@field hl string?
---
---- Character added before the heading name to seperate heading levels
+--- Character added before the heading name to separate heading levels
---@field shift_char string?
---
--- Highlight group for shift_char
@@ -258,10 +258,7 @@
---@class markview.render_config.block_quotes.callouts
---
--- String to match to detect the callout, this is not case-sensitive
----@field match_string string
----
---- Aliases for the callout, this is not case-sensitive
----@field aliases string[]?
+---@field match_string string|string[]
---
--- The text to show for the callout
---@field callout_preview string
@@ -319,7 +316,7 @@
--- Enable/Disable custom hyperlink
---@field enable boolean?
---
----@field inline_links markview.render_config.links.link
+---@field hyperlinks markview.render_config.links.link
---
---@field images markview.render_config.links.link
---
@@ -371,12 +368,6 @@
--- Default highlight group for the various parts
---@field hl string?
---
---- Custom text for the heading. The heading text is used when nil
----@field text string?
----
---- Highlight group for the heading text, inherits from icon_hl
----@field text_hl string?
----
--- Used bu the "label" style to add text before the left padding
---@field corner_left string?
---
diff --git a/lua/markview.lua b/lua/markview.lua
index 3e31206..12008ce 100644
--- a/lua/markview.lua
+++ b/lua/markview.lua
@@ -1,11 +1,11 @@
local markview = {};
local utils = require("markview.utils");
-markview.parser = require("markview/parser");
-markview.renderer = require("markview/renderer");
-markview.keymaps = require("markview/keymaps");
+markview.parser = require("markview.parser");
+markview.renderer = require("markview.renderer");
+markview.keymaps = require("markview.keymaps");
-markview.colors = require("markview/colors");
+markview.colors = require("markview.colors");
markview.add_hls = function (obj)
local use_hl = {};
@@ -43,264 +43,896 @@ markview.global_options = {};
---@type markview.config
markview.configuration = {
- options = {
- on_enable = {
- conceallevel = 2,
- concealcursor = "n"
- },
-
- on_disable = {
- conceallevel = 0,
- concealcursor = ""
- }
+ callbacks = {
+ on_enable = function (buffer, window)
+ vim.wo[window].conceallevel = 2;
+ vim.wo[window].concealcursor = "nc";
+ end,
+ on_disable = function (buffer, window)
+ vim.wo[window].conceallevel = 0;
+ vim.wo[window].concealcursor = "";
+ end,
+
+ on_mode_change = function (buffer, window, mode)
+ if vim.list_contains(markview.configuration.modes, mode) then
+ vim.wo[window].conceallevel = 2;
+ else
+ vim.wo[window].conceallevel = 0;
+ end
+ end
},
highlight_groups = {
+ ---+ ##code##
{
+ -- Heading level 1
output = function ()
- local bg = markview.colors.get_hl_value(0, "Normal", "bg") or markview.colors.get_hl_value(0, "Cursor", "fg");
- local fg = markview.colors.get_hl_value(0, "markdownH1", "fg") or "#f38ba8";
-
- return {
- {
- group_name = "Col1",
- value = {
- bg = markview.colors.mix(bg, fg, 0.7, 0.25),
- fg = fg
- }
- },
- {
- group_name = "Col1Fg",
- value = {
- fg = fg
- }
- },
- {
- group_name = "Col1Inv",
- value = {
- bg = fg,
- fg = bg
- }
- },
- }
+ if markview.colors.get_hl_value(0, "DiagnosticVirtualTextOk", "bg") and markview.colors.get_hl_value(0, "DiagnosticVirtualTextOk", "fg") then
+ local bg = markview.colors.get_hl_value(0, "DiagnosticVirtualTextOk", "bg");
+ local fg = markview.colors.get_hl_value(0, "DiagnosticVirtualTextOk", "fg");
+
+ return {
+ {
+ group_name = "Heading1",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading1Sign",
+ value = {
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ elseif markview.colors.get_hl_value(0, "DiagnosticOk", "fg") and markview.colors.get_hl_value(0, "Normal", "bg") then
+ local bg = markview.colors.get_hl_value(0, "Normal", "bg");
+ local fg = markview.colors.get_hl_value(0, "DiagnosticOk", "fg");
+
+ local nr = markview.colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading1",
+ value = {
+ bg = vim.o.background == "dark"
+ and
+ markview.colors.mix(bg, fg, 0.5, 0.15)
+ or
+ markview.colors.mix(bg, fg, 0.85, 0.20),
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading1Sign",
+ value = {
+ bg = nr,
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ else
+ local bg = markview.colors.get_hl_value(0, "Normal", "bg");
+ local fg = vim.o.background == "dark" and "#a6e3a1" or "#40a02b";
+
+ local nr = markview.colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading1",
+ value = {
+ bg = vim.o.background == "dark"
+ and
+ markview.colors.mix(bg, fg, 0.5, 0.15)
+ or
+ markview.colors.mix(bg, fg, 0.85, 0.20),
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading1Sign",
+ value = {
+ bg = nr,
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ end
end
},
-
{
+ -- Heading level 2
output = function ()
- local bg = markview.colors.get_hl_value(0, "Normal", "bg") or markview.colors.get_hl_value(0, "Cursor", "fg");
- local fg = markview.colors.get_hl_value(0, "markdownH2", "fg") or "#fab387";
-
- return {
- {
- group_name = "Col2",
- value = {
- bg = markview.colors.mix(bg, fg, 0.7, 0.25),
- fg = fg
- }
- },
- {
- group_name = "Col2Fg",
- value = {
- fg = fg
- }
- },
- {
- group_name = "Col2Inv",
- value = {
- bg = fg,
- fg = bg
- }
- },
- }
+ if markview.colors.get_hl_value(0, "DiagnosticVirtualTextHint", "bg") and markview.colors.get_hl_value(0, "DiagnosticVirtualTextHint", "fg") then
+ local bg = markview.colors.get_hl_value(0, "DiagnosticVirtualTextHint", "bg");
+ local fg = markview.colors.get_hl_value(0, "DiagnosticVirtualTextHint", "fg");
+
+ return {
+ {
+ group_name = "Heading2",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading2Sign",
+ value = {
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ elseif markview.colors.get_hl_value(0, "DiagnosticHint", "fg") and markview.colors.get_hl_value(0, "Normal", "bg") then
+ local bg = markview.colors.get_hl_value(0, "Normal", "bg");
+ local fg = markview.colors.get_hl_value(0, "DiagnosticHint", "fg");
+
+ local nr = markview.colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading2",
+ value = {
+ bg = vim.o.background == "dark"
+ and
+ markview.colors.mix(bg, fg, 0.5, 0.15)
+ or
+ markview.colors.mix(bg, fg, 0.85, 0.20),
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading2Sign",
+ value = {
+ bg = nr,
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ else
+ local bg = markview.colors.get_hl_value(0, "Normal", "bg");
+ local fg = vim.o.background == "dark" and "#94e2d5" or "#179299";
+
+ local nr = markview.colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading2",
+ value = {
+ bg = vim.o.background == "dark"
+ and
+ markview.colors.mix(bg, fg, 0.5, 0.15)
+ or
+ markview.colors.mix(bg, fg, 0.85, 0.20),
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading2Sign",
+ value = {
+ bg = nr,
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ end
end
},
-
{
+ -- Heading level 3
output = function ()
- local bg = markview.colors.get_hl_value(0, "Normal", "bg") or markview.colors.get_hl_value(0, "Cursor", "fg");
- local fg = markview.colors.get_hl_value(0, "markdownH3", "fg") or "#f9e2af";
-
- return {
- {
- group_name = "Col3",
- value = {
- bg = markview.colors.mix(bg, fg, 0.7, 0.25),
- fg = fg
- }
- },
- {
- group_name = "Col3Fg",
- value = {
- fg = fg
- }
- },
- {
- group_name = "Col3Inv",
- value = {
- bg = fg,
- fg = bg
- }
- },
- }
+ if markview.colors.get_hl_value(0, "DiagnosticVirtualTextInfo", "bg") and markview.colors.get_hl_value(0, "DiagnosticVirtualTextInfo", "fg") then
+ local bg = markview.colors.get_hl_value(0, "DiagnosticVirtualTextInfo", "bg");
+ local fg = markview.colors.get_hl_value(0, "DiagnosticVirtualTextInfo", "fg");
+
+ return {
+ {
+ group_name = "Heading3",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading3Sign",
+ value = {
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ elseif markview.colors.get_hl_value(0, "DiagnosticInfo", "fg") and markview.colors.get_hl_value(0, "Normal", "bg") then
+ local bg = markview.colors.get_hl_value(0, "Normal", "bg");
+ local fg = markview.colors.get_hl_value(0, "DiagnosticInfo", "fg");
+
+ local nr = markview.colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading3",
+ value = {
+ bg = vim.o.background == "dark"
+ and
+ markview.colors.mix(bg, fg, 0.5, 0.15)
+ or
+ markview.colors.mix(bg, fg, 0.85, 0.20),
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading3Sign",
+ value = {
+ bg = nr,
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ else
+ local bg = markview.colors.get_hl_value(0, "Normal", "bg");
+ local fg = vim.o.background == "dark" and "#89dceb" or "#179299";
+
+ local nr = markview.colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading3",
+ value = {
+ bg = vim.o.background == "dark"
+ and
+ markview.colors.mix(bg, fg, 0.5, 0.15)
+ or
+ markview.colors.mix(bg, fg, 0.85, 0.20),
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading3Sign",
+ value = {
+ bg = nr,
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ end
end
},
-
{
+ -- Heading level 4
output = function ()
- local bg = markview.colors.get_hl_value(0, "Normal", "bg") or markview.colors.get_hl_value(0, "Cursor", "fg");
- local fg = markview.colors.get_hl_value(0, "markdownH4", "fg") or "#a6e3a1";
-
-
- return {
- {
- group_name = "Col4",
- value = {
- bg = markview.colors.mix(bg, fg, 0.7, 0.25),
- fg = fg
- }
- },
- {
- group_name = "Col4Fg",
- value = {
- fg = fg
- }
- },
- {
- group_name = "Col4Inv",
- value = {
- bg = fg,
- fg = bg
- }
- },
- }
+ if markview.colors.get_hl_value(0, "Special", "bg") and markview.colors.get_hl_value(0, "Special", "fg") then
+ local bg = markview.colors.get_hl_value(0, "Special", "bg");
+ local fg = markview.colors.get_hl_value(0, "Special", "fg");
+
+ return {
+ {
+ group_name = "Heading4",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading4Sign",
+ value = {
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ elseif markview.colors.get_hl_value(0, "Special", "fg") and markview.colors.get_hl_value(0, "Normal", "bg") then
+ local bg = markview.colors.get_hl_value(0, "Normal", "bg");
+ local fg = markview.colors.get_hl_value(0, "Special", "fg");
+
+ local nr = markview.colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading4",
+ value = {
+ bg = vim.o.background == "dark"
+ and
+ markview.colors.mix(bg, fg, 0.5, 0.15)
+ or
+ markview.colors.mix(bg, fg, 0.85, 0.20),
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading4Sign",
+ value = {
+ bg = nr,
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ else
+ local bg = markview.colors.get_hl_value(0, "Normal", "bg");
+ local fg = vim.o.background == "dark" and "#f5c2e7" or "#ea76cb";
+
+ local nr = markview.colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading4",
+ value = {
+ bg = vim.o.background == "dark"
+ and
+ markview.colors.mix(bg, fg, 0.5, 0.15)
+ or
+ markview.colors.mix(bg, fg, 0.85, 0.20),
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading4Sign",
+ value = {
+ bg = nr,
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ end
end
},
-
{
+ -- Heading level 5
output = function ()
- local bg = markview.colors.get_hl_value(0, "Normal", "bg") or markview.colors.get_hl_value(0, "Cursor", "fg");
- local fg = markview.colors.get_hl_value(0, "markdownH5", "fg") or "#74c7ec";
-
- return {
- {
- group_name = "Col5",
- value = {
- bg = markview.colors.mix(bg, fg, 0.7, 0.25),
- fg = fg
- }
- },
- {
- group_name = "Col5Fg",
- value = {
- fg = fg
- }
- },
- {
- group_name = "Col5Inv",
- value = {
- bg = fg,
- fg = bg
- }
- },
- }
+ if markview.colors.get_hl_value(0, "DiagnosticVirtualTextWarn", "bg") and markview.colors.get_hl_value(0, "DiagnosticVirtualTextWarn", "fg") then
+ local bg = markview.colors.get_hl_value(0, "DiagnosticVirtualTextWarn", "bg");
+ local fg = markview.colors.get_hl_value(0, "DiagnosticVirtualTextWarn", "fg");
+
+ return {
+ {
+ group_name = "Heading5",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading5Sign",
+ value = {
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ elseif markview.colors.get_hl_value(0, "DiagnosticWarn", "fg") and markview.colors.get_hl_value(0, "Normal", "bg") then
+ local bg = markview.colors.get_hl_value(0, "Normal", "bg");
+ local fg = markview.colors.get_hl_value(0, "DiagnosticWarn", "fg");
+
+ local nr = markview.colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading5",
+ value = {
+ bg = vim.o.background == "dark"
+ and
+ markview.colors.mix(bg, fg, 0.5, 0.15)
+ or
+ markview.colors.mix(bg, fg, 0.85, 0.20),
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading5Sign",
+ value = {
+ bg = nr,
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ else
+ local bg = markview.colors.get_hl_value(0, "Normal", "bg");
+ local fg = vim.o.background == "dark" and "#F9E3AF" or "#DF8E1D";
+
+ local nr = markview.colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading5",
+ value = {
+ bg = vim.o.background == "dark"
+ and
+ markview.colors.mix(bg, fg, 0.5, 0.15)
+ or
+ markview.colors.mix(bg, fg, 0.85, 0.20),
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading5Sign",
+ value = {
+ bg = nr,
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ end
end
},
-
{
+ -- Heading level 6
output = function ()
- local bg = markview.colors.get_hl_value(0, "Normal", "bg") or markview.colors.get_hl_value(0, "Cursor", "fg");
- local fg = markview.colors.get_hl_value(0, "markdownH6", "fg") or "#b4befe";
-
- return {
- {
- group_name = "Col6",
- value = {
- bg = markview.colors.mix(bg, fg, 0.7, 0.25),
- fg = fg
- }
- },
- {
- group_name = "Col6Fg",
- value = {
- fg = fg
- }
- },
- {
- group_name = "Col6Inv",
- value = {
- bg = fg,
- fg = bg
- }
- },
- }
+ if markview.colors.get_hl_value(0, "DiagnosticVirtualTextError", "bg") and markview.colors.get_hl_value(0, "DiagnosticVirtualTextError", "fg") then
+ local bg = markview.colors.get_hl_value(0, "DiagnosticVirtualTextError", "bg");
+ local fg = markview.colors.get_hl_value(0, "DiagnosticVirtualTextError", "fg");
+
+ return {
+ {
+ group_name = "Heading6",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading6Sign",
+ value = {
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ elseif markview.colors.get_hl_value(0, "DiagnosticError", "fg") and markview.colors.get_hl_value(0, "Normal", "bg") then
+ local bg = markview.colors.get_hl_value(0, "Normal", "bg");
+ local fg = markview.colors.get_hl_value(0, "DiagnosticError", "fg");
+
+ local nr = markview.colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading6",
+ value = {
+ bg = vim.o.background == "dark"
+ and
+ markview.colors.mix(bg, fg, 0.5, 0.15)
+ or
+ markview.colors.mix(bg, fg, 0.85, 0.20),
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading6Sign",
+ value = {
+ bg = nr,
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ else
+ local bg = markview.colors.get_hl_value(0, "Normal", "bg");
+ local fg = vim.o.background == "dark" and "#F38BA8" or "#D20F39";
+
+ local nr = markview.colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading6",
+ value = {
+ bg = vim.o.background == "dark"
+ and
+ markview.colors.mix(bg, fg, 0.5, 0.15)
+ or
+ markview.colors.mix(bg, fg, 0.85, 0.20),
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading6Sign",
+ value = {
+ bg = nr,
+ fg = fg,
+
+ default = true
+ }
+ },
+ }
+ end
end
},
+
{
- output = function ()
- local bg = markview.colors.get_hl_value(0, "Normal", "bg") or markview.colors.get_hl_value(0, "Cursor", "fg");
- local fg = markview.colors.get_hl_value(0, "Comment", "fg");
-
- return {
- {
- group_name = "Col7",
- value = {
- bg = markview.colors.mix(bg, fg, 0.7, 0.25),
- fg = fg
- }
- },
- {
- group_name = "Col7Fg",
- value = {
- fg = fg
- }
- },
- {
- group_name = "Col7Inv",
- value = {
- bg = fg,
- fg = bg
- }
- },
- }
+ group_name = "BlockQuoteDefault",
+ value = function ()
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "Comment", "fg"),
+
+ vim.o.background == "dark" and "#6c7086" or "#9ca0b0";
+ });
+
+ return { fg = fg, default = true };
end
},
+ {
+ group_name = "BlockQuoteError",
+ value = function ()
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "DiagnosticError", "fg"),
+
+ vim.o.background == "dark" and "#F38BA8" or "#D20F39";
+ });
+ return { fg = fg, default = true };
+ end
+ },
{
- group_name = "Layer",
+ group_name = "BlockQuoteWarn",
value = function ()
- local bg = markview.colors.get_hl_value(0, "Normal", "bg") or markview.colors.get_hl_value(0, "Cursor", "fg");
- local fg = markview.colors.get_hl_value(0, "Comment", "fg");
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "DiagnosticWarn", "fg"),
- local txt = markview.colors.get_hl_value(0, "FloatTitle", "fg")
+ vim.o.background == "dark" and "#F9E3AF" or "#DF8E1D";
+ });
- return {
- bg = markview.colors.mix(bg, fg, 1, 0.20),
- fg = txt
- }
+ return { fg = fg, default = true };
end
},
{
- group_name = "Layer2",
+ group_name = "BlockQuoteOk",
value = function ()
- local bg = markview.colors.get_hl_value(0, "Normal", "bg") or markview.colors.get_hl_value(0, "Cursor", "fg");
- local fg = markview.colors.get_hl_value(0, "Comment", "fg");
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "DiagnosticOk", "fg"),
- return {
- bg = markview.colors.mix(bg, fg, 0.85, 0.13),
- }
+ vim.o.background == "dark" and "#a6e3a1" or "#40a02b";
+ });
+
+ return { fg = fg, default = true };
+ end
+ },
+ {
+ group_name = "BlockQuoteNote",
+ value = function ()
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "@comment.note", "bg"),
+ markview.colors.get_hl_value(0, "@comment.note", "fg"),
+
+ markview.colors.get_hl_value(0, "Title", "fg"),
+ vim.o.background == "dark" and "#89b4fa" or "#1e66f5"
+ });
+
+ return { fg = fg, default = true };
+ end
+ },
+ {
+ group_name = "BlockQuoteSpecial",
+ value = function ()
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "Conditional", "fg"),
+ markview.colors.get_hl_value(0, "Keyword", "fg"),
+
+ vim.o.background == "dark" and "#cba6f7" or "#8839ef"
+ });
+
+ return { fg = fg, default = true };
+ end
+ },
+
+
+
+ {
+ group_name = "Code",
+ value = function ()
+ local bg = markview.colors.get({
+ markview.colors.get_hl_value(0, "Normal", "bg"),
+ markview.colors.get_hl_value(0, "Cursor", "fg"),
+
+ vim.o.background == "dark" and "#1e1e2e" or "#cdd6f4"
+ });
+
+ local luminosity = markview.colors.get_brightness(bg);
+
+ if luminosity < 0.5 then
+ return {
+ bg = markview.colors.mix(bg, bg, 1, math.max(luminosity, 0.25)),
+ default = true
+ };
+ else
+ return {
+ bg = markview.colors.mix(bg, bg, 1, math.min(luminosity, 0.25) * -1),
+ default = true
+ };
+ end
end
},
+ {
+ group_name = "InlineCode",
+ value = function ()
+ local bg = markview.colors.get({
+ markview.colors.get_hl_value(0, "Normal", "bg"),
+ markview.colors.get_hl_value(0, "Cursor", "fg"),
+
+ vim.o.background == "dark" and "#1e1e2e" or "#cdd6f4"
+ });
+
+ local luminosity = markview.colors.get_brightness(bg);
+
+ if luminosity < 0.5 then
+ return {
+ bg = markview.colors.mix(bg, bg, 1, math.max(luminosity, 0.5)),
+ default = true
+ };
+ else
+ return {
+ bg = markview.colors.mix(bg, bg, 1, math.min(luminosity, 0.5) * -1),
+ default = true
+ };
+ end
+ end
+ },
+
+
+ {
+ group_name = "CheckboxChecked",
+ value = function ()
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "DiagnosticOk", "fg"),
+
+ vim.o.background == "dark" and "#a6e3a1" or "#40a02b";
+ });
+
+ return { fg = fg, default = true };
+ end
+ },
+ {
+ group_name = "CheckboxUnchecked",
+ value = function ()
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "DiagnosticError", "fg"),
+
+ vim.o.background == "dark" and "#F38BA8" or "#D20F39";
+ });
+
+ return { fg = fg, default = true };
+ end
+ },
+ {
+ group_name = "CheckboxPending",
+ value = function ()
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "DiagnosticWarn", "fg"),
+
+ vim.o.background == "dark" and "#F9E3AF" or "#DF8E1D";
+ });
+
+ return { fg = fg, default = true };
+ end
+ },
+
+
+ {
+ group_name = "TableBorder",
+ value = function ()
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "@comment.note", "bg"),
+ markview.colors.get_hl_value(0, "@comment.note", "fg"),
+
+ markview.colors.get_hl_value(0, "Title", "fg"),
+ vim.o.background == "dark" and "#89b4fa" or "#1e66f5"
+ });
+
+ return { fg = fg, default = true };
+ end
+ },
+ {
+ group_name = "TableAlignLeft",
+ value = function ()
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "@comment.note", "bg"),
+ markview.colors.get_hl_value(0, "@comment.note", "fg"),
+
+ markview.colors.get_hl_value(0, "Title", "fg"),
+ vim.o.background == "dark" and "#89b4fa" or "#1e66f5"
+ });
+
+ return { fg = fg, default = true };
+ end
+ },
+ {
+ group_name = "TableAlignRight",
+ value = function ()
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "@comment.note", "bg"),
+ markview.colors.get_hl_value(0, "@comment.note", "fg"),
+
+ markview.colors.get_hl_value(0, "Title", "fg"),
+ vim.o.background == "dark" and "#89b4fa" or "#1e66f5"
+ });
+
+ return { fg = fg, default = true };
+ end
+ },
+ {
+ group_name = "TableAlignCenter",
+ value = function ()
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "@comment.note", "bg"),
+ markview.colors.get_hl_value(0, "@comment.note", "fg"),
+
+ markview.colors.get_hl_value(0, "Title", "fg"),
+ vim.o.background == "dark" and "#89b4fa" or "#1e66f5"
+ });
+
+ return { fg = fg, default = true };
+ end
+ },
+
+
+ {
+ group_name = "ListItemMinus",
+ value = function ()
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "DiagnosticWarn", "fg"),
+
+ vim.o.background == "dark" and "#F9E3AF" or "#DF8E1D";
+ });
+
+ return { fg = fg, default = true };
+ end
+ },
+ {
+ group_name = "ListItemPlus",
+ value = function ()
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "DiagnosticOk", "fg"),
+
+ vim.o.background == "dark" and "#a6e3a1" or "#40a02b";
+ });
+
+ return { fg = fg, default = true };
+ end
+ },
+ {
+ group_name = "ListItemStar",
+ value = function ()
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "@comment.note", "bg"),
+ markview.colors.get_hl_value(0, "@comment.note", "fg"),
+
+ markview.colors.get_hl_value(0, "Title", "fg"),
+ vim.o.background == "dark" and "#89b4fa" or "#1e66f5"
+ });
+
+ return { fg = fg, default = true };
+ end
+ },
+
+
+ {
+ group_name = "Hyperlink",
+ value = function ()
+ if markview.colors.get_hl_value(0, "markdownLinkText", "fg") then
+ return { link = "markdownLinkText", default = true };
+ elseif markview.colors.get_hl_value(0, "@markup.link.label.markdown_inline", "fg") then
+ return { link = "@markup.link.label.markdown_inline", default = true };
+ end
+
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "Label", "fg"),
+
+ vim.o.background == "dark" and "#74c7ec" or "#209fb5"
+ });
+
+ return { fg = fg, underline = true, default = true };
+ end
+ },
+ {
+ group_name = "ImageLink",
+ value = function ()
+ if markview.colors.get_hl_value(0, "markdownLinkText", "fg") then
+ return { link = "markdownLinkText", default = true };
+ elseif markview.colors.get_hl_value(0, "@markup.link.label.markdown_inline", "fg") then
+ return { link = "@markup.link.label.markdown_inline", default = true };
+ end
+
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "Label", "fg"),
+
+ vim.o.background == "dark" and "#74c7ec" or "#209fb5"
+ });
+
+ return { fg = fg, underline = true, default = true };
+ end
+ },
+ {
+ group_name = "Email",
+ value = function ()
+ if markview.colors.get_hl_value(0, "@markup.link.url.markdown_inline", "fg") then
+ return { link = "@markup.link.url.markdown_inline", default = true };
+ elseif markview.colors.get_hl_value(0, "@markup.link.url", "fg") then
+ return { link = "@markup.link.url", default = true };
+ end
+
+ local fg = markview.colors.get({
+ markview.colors.get_hl_value(0, "Label", "fg"),
+
+ vim.o.background == "dark" and "#f5e0dc" or "#dc8a78"
+ });
+
+ return { fg = fg, underline = true, default = true };
+ end
+ },
+
+
{
output = function ()
return markview.colors.create_gradient("Gradient", markview.colors.get_hl_value(0, "Normal", "bg") or markview.colors.get_hl_value(0, "Cursor", "fg"), markview.colors.get_hl_value(0, "Title", "fg"), 10, "fg");
end
}
+ ---_
},
buf_ignore = { "nofile" },
modes = { "n", "no" },
+ special_modes = nil,
headings = {
enable = true,
@@ -308,48 +940,48 @@ markview.configuration = {
heading_1 = {
style = "icon",
- sign = " ", sign_hl = "MarkviewCol1Fg",
+ sign = " ", sign_hl = "MarkviewHeading1Sign",
- icon = " ", hl = "MarkviewCol1",
+ icon = " ", hl = "MarkviewHeading1",
},
heading_2 = {
style = "icon",
- sign = " ", sign_hl = "MarkviewCol2Fg",
+ sign = " ", sign_hl = "MarkviewHeading2Sign",
- icon = " ", hl = "MarkviewCol2",
+ icon = " ", hl = "MarkviewHeading2",
},
heading_3 = {
style = "icon",
- icon = " ", hl = "MarkviewCol3",
+ icon = " ", hl = "MarkviewHeading3",
},
heading_4 = {
style = "icon",
- icon = " ", hl = "MarkviewCol4",
+ icon = " ", hl = "MarkviewHeading4",
},
heading_5 = {
style = "icon",
- icon = " ", hl = "MarkviewCol5",
+ icon = " ", hl = "MarkviewHeading5",
},
heading_6 = {
style = "icon",
- icon = " ", hl = "MarkviewCol6",
+ icon = " ", hl = "MarkviewHeading6",
},
setext_1 = {
style = "github",
- icon = " ", hl = "MarkviewCol1",
+ icon = " ", hl = "MarkviewHeading1",
underline = "━"
},
setext_2 = {
style = "github",
- icon = " ", hl = "MarkviewCol2",
+ icon = " ", hl = "MarkviewHeading2",
underline = "─"
}
},
@@ -358,7 +990,7 @@ markview.configuration = {
enable = true,
style = "language",
- hl = "Layer2",
+ hl = "MarkviewCode",
min_width = 60,
pad_amount = 3,
@@ -376,7 +1008,7 @@ markview.configuration = {
enable = true,
default = {
- border = "▋", border_hl = "MarkviewCol7Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteDefault"
},
callouts = {
@@ -384,139 +1016,139 @@ markview.configuration = {
{
match_string = "ABSTRACT",
callout_preview = " Abstract",
- callout_preview_hl = "MarkviewCol5Fg",
+ callout_preview_hl = "MarkviewBlockQuoteNote",
custom_title = true,
custom_icon = " ",
- border = "▋", border_hl = "MarkviewCol5Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteNote"
},
{
match_string = "TODO",
callout_preview = " Todo",
- callout_preview_hl = "MarkviewCol5Fg",
+ callout_preview_hl = "MarkviewBlockQuoteNote",
custom_title = true,
custom_icon = " ",
- border = "▋", border_hl = "MarkviewCol5Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteNote"
},
{
match_string = "SUCCESS",
callout_preview = " Success",
- callout_preview_hl = "MarkviewCol4Fg",
+ callout_preview_hl = "MarkviewBlockQuoteOk",
custom_title = true,
custom_icon = " ",
- border = "▋", border_hl = "MarkviewCol4Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteOk"
},
{
match_string = "QUESTION",
callout_preview = " Question",
- callout_preview_hl = "MarkviewCol2Fg",
+ callout_preview_hl = "MarkviewBlockQuoteWarn",
custom_title = true,
custom_icon = " ",
- border = "▋", border_hl = "MarkviewCol2Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteWarn"
},
{
match_string = "FAILURE",
callout_preview = " Failure",
- callout_preview_hl = "MarkviewCol1Fg",
+ callout_preview_hl = "MarkviewBlockQuoteError",
custom_title = true,
custom_icon = " ",
- border = "▋", border_hl = "MarkviewCol1Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteError"
},
{
match_string = "DANGER",
callout_preview = " Danger",
- callout_preview_hl = "MarkviewCol1Fg",
+ callout_preview_hl = "MarkviewBlockQuoteError",
custom_title = true,
custom_icon = " ",
- border = "▋", border_hl = "MarkviewCol1Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteError"
},
{
match_string = "BUG",
callout_preview = " Bug",
- callout_preview_hl = "MarkviewCol1Fg",
+ callout_preview_hl = "MarkviewBlockQuoteError",
custom_title = true,
custom_icon = " ",
- border = "▋", border_hl = "MarkviewCol1Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteError"
},
{
match_string = "EXAMPLE",
callout_preview = " Example",
- callout_preview_hl = "MarkviewCol6Fg",
+ callout_preview_hl = "MarkviewBlockQuoteSpecial",
custom_title = true,
custom_icon = " ",
- border = "▋", border_hl = "MarkviewCol6Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteSpecial"
},
{
match_string = "QUOTE",
callout_preview = " Quote",
- callout_preview_hl = "MarkviewCol7Fg",
+ callout_preview_hl = "MarkviewBlockQuoteDefault",
custom_title = true,
custom_icon = " ",
- border = "▋", border_hl = "MarkviewCol7Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteDefault"
},
{
match_string = "NOTE",
callout_preview = " Note",
- callout_preview_hl = "MarkviewCol5Fg",
+ callout_preview_hl = "MarkviewBlockQuoteNote",
- border = "▋", border_hl = "MarkviewCol5Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteNote"
},
{
match_string = "TIP",
callout_preview = " Tip",
- callout_preview_hl = "MarkviewCol4Fg",
+ callout_preview_hl = "MarkviewBlockQuoteOk",
- border = "▋", border_hl = "MarkviewCol4Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteOk"
},
{
match_string = "IMPORTANT",
callout_preview = " Important",
- callout_preview_hl = "MarkviewCol3Fg",
+ callout_preview_hl = "MarkviewBlockQuoteSpecial",
- border = "▋", border_hl = "MarkviewCol3Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteSpecial"
},
{
match_string = "WARNING",
callout_preview = " Warning",
- callout_preview_hl = "MarkviewCol2Fg",
+ callout_preview_hl = "MarkviewBlockQuoteWarn",
- border = "▋", border_hl = "MarkviewCol2Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteWarn"
},
{
match_string = "CAUTION",
callout_preview = " Caution",
- callout_preview_hl = "MarkviewCol1Fg",
+ callout_preview_hl = "MarkviewBlockQuoteError",
- border = "▋", border_hl = "MarkviewCol1Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteError"
},
{
match_string = "CUSTOM",
callout_preview = " Custom",
- callout_preview_hl = "MarkviewCol3Fg",
+ callout_preview_hl = "MarkviewBlockQuoteWarn",
custom_title = true,
custom_icon = " ",
- border = "▋", border_hl = "MarkviewCol3Fg"
+ border = "▋", border_hl = "MarkviewBlockQuoteWarn"
}
}
},
@@ -557,21 +1189,46 @@ markview.configuration = {
}
}
},
+ html = {
+ tags = {
+ enable = true,
+
+ default = {
+ conceal = false
+ },
+
+ configs = {
+ b = { conceal = true, hl = "Bold" },
+ strong = { conceal = true, hl = "Bold" },
+
+ u = { conceal = true, hl = "Underlined" },
+
+ i = { conceal = true, hl = "Italic" },
+ emphasize = { conceal = true, hl = "Italic" },
+
+ marked = { conceal = true, hl = "Special" },
+ }
+ },
+
+ entites = {
+ enable = true
+ }
+ },
links = {
enable = true,
- inline_links = {
- icon = " ", icon_hl = "markdownLinkText",
- hl = "markdownLinkText",
+ hyperlinks = {
+ icon = " ",
+ hl = "MarkviewHyperlink",
},
images = {
- icon = " ", icon_hl = "markdownLinkText",
- hl = "markdownLinkText",
+ icon = " ",
+ hl = "MarkviewImageLink",
},
emails = {
- icon = " ", icon_hl = "@markup.link.url",
- hl = "@markup.link.url",
+ icon = " ",
+ hl = "MarkviewEmail",
}
},
@@ -580,7 +1237,7 @@ markview.configuration = {
corner_left = " ",
corner_right = " ",
- hl = "Layer"
+ hl = "MarkviewInlineCode"
},
list_items = {
@@ -588,19 +1245,19 @@ markview.configuration = {
add_padding = true,
text = "",
- hl = "markviewCol2Fg"
+ hl = "MarkviewListItemMinus"
},
marker_plus = {
add_padding = true,
text = "",
- hl = "markviewCol4Fg"
+ hl = "MarkviewListItemPlus"
},
marker_star = {
add_padding = true,
text = "",
- text_hl = "markviewCol6Fg"
+ text_hl = "MarkviewListItemStar"
},
marker_dot = {
add_padding = true
@@ -611,13 +1268,13 @@ markview.configuration = {
enable = true,
checked = {
- text = "✔", hl = "markviewCol4Fg"
+ text = "✔", hl = "MarkviewCheckboxChecked"
},
pending = {
- text = "◯", hl = "MarkviewCol2Fg"
+ text = "◯", hl = "MarkviewCheckboxPending"
},
unchecked = {
- text = "✘", hl = "MarkviewCol1Fg"
+ text = "✘", hl = "MarkviewCheckboxUnchecked"
}
},
@@ -631,14 +1288,14 @@ markview.configuration = {
"╼", "╾", "╴", "╶"
},
hl = {
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg",
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg",
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg",
+ "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder",
+ "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder",
+ "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder",
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg"
+ "MarkviewTableAlignLeft", "MarkviewTableAlignRight", "MarkviewTableAlignCenter", "MarkviewTableAlignCenter"
},
- use_virt_lines = false
+ use_virt_lines = true
},
};
@@ -661,13 +1318,15 @@ markview.commands = {
for _, buf in ipairs(markview.attached_buffers) do
local parsed_content = markview.parser.init(buf);
local windows = utils.find_attached_wins(buffer);
- local options = markview.configuration.options or {};
- for _, window in ipairs(windows) do
- vim.wo[window].conceallevel = type(options.on_enable) == "table" and options.on_enable.conceallevel or 2;
- vim.wo[window].concealcursor = type(options.on_enable) == "table" and options.on_enable.concealcursor or "n";
+ if markview.configuration.callbacks and markview.configuration.callbacks.on_enable then
+ for _, window in ipairs(windows) do
+ pcall(markview.configuration.callbacks.on_enable, buf, window);
+ end
end
+ markview.state.buf_states[buf] = true;
+
markview.renderer.clear(buf);
markview.renderer.render(buf, parsed_content, markview.configuration)
end
@@ -675,13 +1334,15 @@ markview.commands = {
disableAll = function ()
for _, buf in ipairs(markview.attached_buffers) do
local windows = utils.find_attached_wins(buffer);
- local options = markview.configuration.options or {};
- for _, window in ipairs(windows) do
- vim.wo[window].conceallevel = type(options.on_disable) == "table" and options.on_disable.conceallevel or markview.global_options.conceallevel;
- vim.wo[window].concealcursor = type(options.on_disable) == "table" and options.on_disable.concealcursor or markview.global_options.concealcursor;
+ if markview.configuration.callbacks and markview.configuration.callbacks.on_disable then
+ for _, window in ipairs(windows) do
+ pcall(markview.configuration.callbacks.on_disable, buf, window);
+ end
end
+ markview.state.buf_states[buf] = false;
+
markview.renderer.clear(buf);
end
@@ -707,7 +1368,6 @@ markview.commands = {
end,
enable = function (buf)
local buffer = tonumber(buf) or vim.api.nvim_get_current_buf();
- local options = markview.configuration.options or {};
if not vim.list_contains(markview.attached_buffers, buffer) or not vim.api.nvim_buf_is_valid(buffer) then
return;
@@ -720,8 +1380,7 @@ markview.commands = {
markview.state.buf_states[buffer] = true;
for _, window in ipairs(windows) do
- vim.wo[window].conceallevel = type(options.on_enable) == "table" and options.on_enable.conceallevel or 2;
- vim.wo[window].concealcursor = type(options.on_enable) == "table" and options.on_enable.concealcursor or "n";
+ pcall(markview.configuration.callbacks.on_enable, buf, window);
end
markview.renderer.clear(buffer);
@@ -730,7 +1389,6 @@ markview.commands = {
disable = function (buf)
local buffer = tonumber(buf) or vim.api.nvim_get_current_buf();
- local options = markview.configuration.options or {};
if not vim.list_contains(markview.attached_buffers, buffer) or not vim.api.nvim_buf_is_valid(buffer) then
return;
@@ -739,8 +1397,7 @@ markview.commands = {
local windows = utils.find_attached_wins(buffer);
for _, window in ipairs(windows) do
- vim.wo[window].conceallevel = type(options.on_disable) == "table" and options.on_disable.conceallevel or markview.global_options.conceallevel;
- vim.wo[window].concealcursor = type(options.on_disable) == "table" and options.on_disable.concealcursor or markview.global_options.concealcursor;
+ pcall(markview.configuration.callbacks.on_disable, buf, window);
end
markview.renderer.clear(buffer);
@@ -817,7 +1474,6 @@ end, {
end
})
-
markview.setup = function (user_config)
---@type markview.config
-- Merged configuration tables
diff --git a/lua/markview/colors.lua b/lua/markview/colors.lua
index fd77497..26552a8 100644
--- a/lua/markview/colors.lua
+++ b/lua/markview/colors.lua
@@ -8,7 +8,55 @@ colors.lerp = function (x, y, t)
return x + ((y - x) * t);
end
+colors.name_to_hex = function (name)
+ local lookup = {
+ ["red"] = "#FF0000", ["lightred"] = "#FFBBBB", ["darkred"] = "#8B0000",
+ ["green"] = "#00FF00", ["lightgreen"] = "#90EE90", ["darkgreen"] = "#006400", ["seagreen"] = "#2E8B57",
+ ["blue"] = "#0000FF", ["lightblue"] = "#ADD8E6", ["darkblue"] = "#00008B", ["slateblue"] = "#6A5ACD",
+ ["cyan"] = "#00FFFF", ["lightcyan"] = "#E0FFFF", ["darkcyan"] = "#008B8B",
+ ["magenta"] = "#FF00FF", ["lightmagenta"] = "#FFBBFF", ["darkmagenta"] = "#8B008B",
+ ["yellow"] = "#FFFF00", ["lightyellow"] = "#FFFFE0", ["darkyellow"] = "#BBBB00", ["brown"] = "#A52A2A",
+ ["grey"] = "#808080", ["lightgrey"] = "#D3D3D3", ["darkgrey"] = "#A9A9A9",
+ ["gray"] = "#808080", ["lightgray"] = "#D3D3D3", ["darkgray"] = "#A9A9A9",
+ ["black"] = "#000000", ["white"] = "#FFFFFF",
+ ["orange"] = "#FFA500", ["purple"] = "#800080", ["violet"] = "#EE82EE"
+ };
+
+ local lookup_nvim = {
+ ["nvimdarkblue"] = "#004C73", ["nvimlightblue"] = "#A6DBFF",
+ ["nvimdarkcyan"] = "#007373", ["nvimlightcyan"] = "#8CF8F7",
+ ["nvimdarkgray1"] = "#07080D", ["nvimlightgray1"] = "#EEF1F8",
+ ["nvimdarkgray2"] = "#14161B", ["nvimlightgray2"] = "#E0E2EA",
+ ["nvimdarkgray3"] = "#2C2E33", ["nvimlightgray3"] = "#C4C6CD",
+ ["nvimdarkgray4"] = "#4F5258", ["nvimlightgray4"] = "#9B9EA4",
+ ["nvimdarkgrey1"] = "#07080D", ["nvimlightgrey1"] = "#EEF1F8",
+ ["nvimdarkgrey2"] = "#14161B", ["nvimlightgrey2"] = "#E0E2EA",
+ ["nvimdarkgrey3"] = "#2C2E33", ["nvimlightgrey3"] = "#C4C6CD",
+ ["nvimdarkgrey4"] = "#4F5258", ["nvimlightgrey4"] = "#9B9EA4",
+ ["nvimdarkgreen"] = "#005523", ["nvimlightgreen"] = "#B3F6C0",
+ ["nvimdarkmagenta"] = "#470045", ["nvimlightmagenta"] = "#FFCAFF",
+ ["nvimdarkred"] = "#590008", ["nvimlightred"] = "#FFC0B9",
+ ["nvimdarkyellow"] = "#6B5300", ["nvimlightyellow"] = "#FCE094",
+ };
+
+ return lookup[string.lower(name)] or lookup_nvim[string.lower(name)];
+end
+
+colors.name_to_rgb = function (name)
+ local hex = colors.name_to_hex(name);
+
+ if not hex then
+ return;
+ end
+
+ return colors.hex_to_rgb(hex);
+end
+
colors.num_to_hex = function (num)
+ if not num then
+ return;
+ end
+
if num == 0 then
return "#000000";
elseif num ~= nil then
@@ -17,6 +65,10 @@ colors.num_to_hex = function (num)
end
colors.num_to_rgb = function (num)
+ if not num then
+ return;
+ end
+
local hex = string.format("%x", num);
return {
@@ -49,14 +101,30 @@ colors.rgb_to_hex = function (tbl)
end
colors.get_hl_value = function (ns_id, hl_group, value)
- local hl = vim.api.nvim_get_hl(ns_id, { name = hl_group, link = false });
+ if vim.fn.hlexists(hl_group) == 0 then
+ return;
+ end
+
+ local hl = vim.api.nvim_get_hl(ns_id, { name = hl_group, link = false, create = false });
if value == "fg" then
- return colors.num_to_hex(hl.fg)
+ if type(hl.fg) == "string" and hl.fg:match("^[#]?(%x+)$") then
+ return colors.name_to_hex(hl.fg)
+ else
+ return colors.num_to_hex(hl.fg)
+ end
elseif value == "bg" then
- return colors.num_to_hex(hl.bg)
+ if type(hl.bg) == "string" and hl.bg:match("^[#]?(%x+)$") then
+ return colors.name_to_hex(hl.bg)
+ else
+ return colors.num_to_hex(hl.bg)
+ end
elseif value == "sp" then
- return colors.num_to_hex(hl.sp)
+ if type(hl.sp) == "string" and hl.sp:match("^[#]?(%x+)$") then
+ return colors.name_to_hex(hl.sp)
+ else
+ return colors.num_to_hex(hl.sp)
+ end
else
return hl[value];
end
@@ -109,14 +177,18 @@ colors.mix = function (color_1, color_2, per_1, per_2)
if type(color_1) == "table" then
c_1 = color_1;
- elseif type(color_1) == "string" then
+ elseif type(color_1) == "string" and color_1:match("^[#]?(%x+)$") then
c_1 = colors.hex_to_rgb(color_1);
+ elseif type(color_1) == "string" then
+ c_1 = colors.name_to_rgb(color_1);
end
if type(color_2) == "table" then
c_2 = color_2;
- elseif type(color_2) == "string" then
+ elseif type(color_2) == "string" and color_2:match("^[#]?(%x+)$") then
c_2 = colors.hex_to_rgb(color_2);
+ elseif type(color_2) == "string" then
+ c_1 = colors.name_to_rgb(color_2);
end
if not c_1 or not c_2 then
@@ -130,4 +202,85 @@ colors.mix = function (color_1, color_2, per_1, per_2)
return colors.rgb_to_hex({ r = _r, g = _g, b = _b });
end
+colors.get_brightness = function (color)
+ if type(color) == "string" and color:match("^[#]?(%x+)$") then
+ color = colors.hex_to_rgb(color);
+ elseif type(color_1) == "string" then
+ color = colors.name_to_rgb(color);
+ elseif type(color) == "number" then
+ color = colors.num_to_rgb(color);
+ end
+
+ for key, value in pairs(color) do
+ if value > 1 then
+ color[key] = value / 255;
+ end
+ end
+
+ return (color.r * 0.2126) + (color.g * 0.7152) + (color.b * 0.0722);
+end
+
+colors.brightest = function (col_list, debug)
+ if not col_list then
+ return;
+ elseif not vim.islist(col_list) then
+ local tmp = {};
+
+ for _, item in pairs(col_list) do
+ table.insert(tmp,item);
+ end
+
+ col_list = tmp;
+ end
+
+ local _c = {};
+
+ for _, col in ipairs(col_list) do
+ if type(col) == "string" and col:match("^[#]?(%x+)$") then
+ table.insert(_c, colors.hex_to_rgb(col));
+ elseif type(col) == "string" then
+ table.insert(_c, colors.name_to_rgb(col));
+ elseif type(col) == "number" then
+ table.insert(_c, colors.num_to_rgb(col));
+ elseif type(col) == "table" then
+ table.insert(_c, col);
+ end
+ end
+
+
+ local _b = 0;
+ local brightest;
+
+ for _, c in ipairs(_c) do
+ local brightness = colors.get_brightness(c) or 0;
+
+ if brightness >= _b then
+ _b = brightness;
+ brightest = c;
+ end
+ end
+
+ -- if debug then
+ -- vim.print(colors.rgb_to_hex(brightest) == nil);
+ -- end
+
+ return colors.rgb_to_hex(brightest);
+end
+
+colors.get = function (col_list)
+ if not col_list then
+ return;
+ elseif not vim.islist(col_list) then
+ local tmp = {};
+
+ for _, item in pairs(col_list) do
+ table.insert(tmp,item);
+ end
+
+ col_list = tmp;
+ end
+
+ return col_list[1];
+end
+
return colors;
diff --git a/lua/markview/entites.lua b/lua/markview/entites.lua
new file mode 100644
index 0000000..c0beec5
--- /dev/null
+++ b/lua/markview/entites.lua
@@ -0,0 +1,256 @@
+local entites = {};
+
+entites.lookup = {
+ Aacute = "Á",
+ aacute = "á",
+ Acirc = "Â",
+ acirc = "â",
+ acute = "´",
+ AElig = "Æ",
+ aelig = "æ",
+ Agrave = "À",
+ agrave = "à",
+ alefsym = "ℵ",
+ Alpha = "Α",
+ alpha = "α",
+ amp = "&",
+ ["and"] = "∧",
+ ang = "∠",
+ Aring = "Å",
+ aring = "å",
+ asymp = "≈",
+ Atilde = "Ã",
+ atilde = "ã",
+ Auml = "Ä",
+ auml = "ä",
+ bdquo = "„",
+ Beta = "Β",
+ beta = "β",
+ brvbar = "¦",
+ bull = "•",
+ cap = "∩",
+ Ccedil = "Ç",
+ ccedil = "ç",
+ cedil = "¸",
+ cent = "¢",
+ Chi = "Χ",
+ chi = "χ",
+ circ = "ˆ",
+ clubs = "♣",
+ congc = "≅",
+ copy = "©",
+ crarr = "↵",
+ cup = "∪",
+ curren = "¤",
+ Dagger = "‡",
+ dagger = "†",
+ dArr = "⇓",
+ darr = "↓",
+ deg = "°",
+ Delta = "Δ",
+ delta = "δ",
+ diams = "♦",
+ divide = "÷",
+ Eacute = "É",
+ eacute = "é",
+ Ecirc = "Ê",
+ ecirc = "ê",
+ Egrave = "È",
+ egrave = "è",
+ empty = "∅",
+ Epsilon = "Ε",
+ epsilon = "ε",
+ equiv = "≡",
+ Eta = "Η",
+ eta = "η",
+ ETH = "Ð",
+ eth = "ð",
+ Euml = "Ë",
+ euml = "ë",
+ euro = "€",
+ exists = "∃",
+ fnof = "ƒ",
+ forall = "∀",
+ frac12 = "½",
+ frac14 = "¼",
+ frac34 = "¾",
+ frasl = "⁄",
+ Gamma = "Γ",
+ gamma = "γ",
+ ge = "≥",
+ gt = ">",
+ harr = "↔",
+ hArr = "⇔",
+ hearts = "♥",
+ hellip = "…",
+ Iacute = "Í",
+ iacute = "í",
+ Icirc = "Î",
+ icirc = "î",
+ iexcl = "¡",
+ Igrave = "Ì",
+ igrave = "ì",
+ image = "ℑ",
+ infin = "∞",
+ int = "∫",
+ Iota = "Ι",
+ iota = "ι",
+ iquest = "¿",
+ isin = "∈",
+ Iuml = "Ï",
+ iuml = "ï",
+ Kappa = "Κ",
+ kappa = "κ",
+ Lambda = "Λ",
+ lambda = "λ",
+ lang = "⟨",
+ laquo = "«",
+ lArr = "⇐",
+ larr = "←",
+ lceil = "⌈",
+ ldquo = "“",
+ le = "≤",
+ lfloor = "⌊",
+ lowast = "∗",
+ loz = "◊",
+ -- lrm = "",
+ lsaquo = "‹",
+ lsquo = "‘",
+ lt = "<",
+ macr = "¯",
+ mdash = "—",
+ micro = "µ",
+ middot = "·",
+ minus = "−",
+ Mu = "Μ",
+ mu = "μ",
+ nabla = "∇",
+ nbsp = " ",
+ ndash = "–",
+ ne = "≠",
+ ni = "∋",
+ ["not"] = "¬",
+ notin = "∉",
+ nsub = "⊄",
+ Ntilde = "Ñ",
+ ntilde = "ñ",
+ Nu = "Ν",
+ nu = "ν",
+ Oacute = "Ó",
+ oacute = "ó",
+ Ocirc = "Ô",
+ ocirc = "ô",
+ OElig = "Œ",
+ oelig = "œ",
+ Ograve = "Ò",
+ ograve = "ò",
+ Omeg = "Ω",
+ omega = "ω",
+ Omicron = "Ο",
+ omicron = "ο",
+ oline = "‾",
+ ["or"] = "∨",
+ Oslash = "Ø",
+ oslash = "ø",
+ Otilde = "Õ",
+ otilde = "õ",
+ Ouml = "Ö",
+ ouml = "ö",
+ para = "¶",
+ part = "∂",
+ permil = "‰",
+ perp = "⊥",
+ Phi = "Φ",
+ phi = "φ",
+ Pi = "Π",
+ pi = "π",
+ piv = "ϖ",
+ plusmn = "±",
+ pound = "£",
+ Prime = "″",
+ prime = "′",
+ prod = "∏",
+ prop = "∝",
+ Psi = "Ψ",
+ psi = "ψ",
+ quot = "\"",
+ radic = "√",
+ rang = "⟩",
+ raquo = "»",
+ rArr = "⇒",
+ rarr = "→",
+ rceil = "⌉",
+ rdquo = "”",
+ real = "ℜ",
+ reg = "®",
+ rflo = "⌋",
+ Rho = "Ρ",
+ rho = "ρ",
+ -- rlm = "",
+ rsaquo = "›",
+ rsquo = "’",
+ sbquo = "‚",
+ Scaron = "Š",
+ scaron = "š",
+ sdot = "⋅",
+ sect = "§",
+ shy = "",
+ Sigma = "Σ",
+ sigma = "σ",
+ sigmaf = "ς",
+ sim = "∼",
+ spades = "♠",
+ sub = "⊂",
+ sube = "⊆",
+ sum = "∑",
+ sup = "⊃",
+ sup1 = "¹",
+ sup2 = "²",
+ sup3 = "³",
+ supe = "⊇",
+ szlig = "ß",
+ Tau = "Τ",
+ tau = "τ",
+ there4 = "∴",
+ Theta = "Θ",
+ theta = "θ",
+ thetasym = "ϑ",
+ thinsp = " ",
+ THORN = "Þ",
+ thorn = "þ",
+ tilde = "˜",
+ times = "×",
+ trade = "™",
+ Uacute = "Ú",
+ uacute = "ú",
+ uArr = "⇑",
+ uarr = "↑",
+ Ucirc = "Û",
+ ucirc = "û",
+ Ugrave = "Ù",
+ ugrave = "ù",
+ uml = "¨",
+ upsih = "ϒ",
+ Upsilon = "Υ",
+ upsilon = "υ",
+ Uuml = "Ü",
+ uuml = "ü",
+ weierp = "℘",
+ Xi = "Ξ",
+ xi = "ξ",
+ Yacute = "Ý",
+ yacute = "ý",
+ yen = "¥",
+ yuml = "ÿ",
+ Yuml = "Ÿ",
+ Zeta = "Ζ",
+ zeta = "ζ",
+ -- zwj = "",
+ -- zwnj = ""
+}
+
+entites.get = function (string)
+ return entites.lookup[string], vim.fn.strdisplaywidth(entites.lookup[string]);
+end
+
+return entites;
diff --git a/lua/markview/extras.lua b/lua/markview/extras.lua
index c4a1bf9..8654bba 100644
--- a/lua/markview/extras.lua
+++ b/lua/markview/extras.lua
@@ -1,3 +1,5 @@
+-- For testing purposes
+
local extras = {};
extras.show_headings = {
diff --git a/lua/markview/languages.lua b/lua/markview/languages.lua
new file mode 100644
index 0000000..64607ca
--- /dev/null
+++ b/lua/markview/languages.lua
@@ -0,0 +1,221 @@
+local languages = {};
+
+languages.patterns = {
+ { ".*%.feature", "Cucumber" },
+
+ { ".*%.abap", "Abap" },
+
+ { ".*%.ada", "Ada" },
+ { "adb", "Ada" },
+ { "ads$", "Ada" },
+
+ { "htaccess", "Apacheconf" },
+ { "apache.conf", "Apacheconf" },
+ { "apache2.conf", "Apacheconf" },
+
+ { ".*%.as", "As" },
+ { ".%*%.asy", "Asy" },
+
+ { "ahkl", "Ahk" },
+
+ { "sh", "Bash" },
+ { "ksh", "Bash" },
+ { "ksh", "Bash" },
+ { ".*%.ebuild", "Bash" },
+ { ".*%.eclass", "Bash" },
+
+ { ".*%.befunge", "Befunge" },
+ { ".*%.bmx", "Blitzmax" },
+ { ".*%.boo", "Boo" },
+
+ { "bf", "Brainfuck" },
+ { "b", "Brainfuck" },
+
+ { "cmd", "Bat" },
+
+ { ".*%.cfc", "Cfm" },
+ { "cfml", "Cfm" },
+
+ { "cl", "Cl" },
+ { "lisp", "Cl" },
+ { ".*%.el", "Cl" },
+
+ { "clj", "Clojure" },
+ { "cljs", "Clojure" },
+
+ { "h", "C" },
+ { "c", "C" },
+ { ".*.cmake", "Cmake" },
+
+ { "coffee", "Cofeescript" },
+ { ".*%.sh%-session", "Console" },
+
+ { "cpp", "C++" },
+ { "hpp", "C++" },
+ { "cc", "C++" },
+ { "hh", "C++" },
+ { "cxx", "C++" },
+ { "hxx", "C++" },
+ { ".*%.pde", "C++" },
+
+ { "csharp", "C#" },
+ { "cs", "C#" },
+ { ".*.%cs", "C#" },
+
+ { "css", "CSS" },
+
+ { "pyx", "Cython" },
+ { "pxd", "Cython" },
+ { ".*%.pxi", "Cython" },
+
+ { "d", "D" },
+ { "di", "D" },
+
+ { ".*%.pas", "Delphi" },
+
+ { "patch", "Diff" },
+
+ { "darcspatch", "Dpatch" },
+
+ { "jbst", "Duel" },
+
+ { "dyl", "Dylan" },
+
+ { ".*%.erb", "Erb" },
+
+ { ".*%.erl%-sh", "Erl" },
+
+ { "erl", "Erlang" },
+ { "hrl", "Erlang" },
+
+ { "flx", "Felix" },
+ { "flxh", "Felix" },
+
+ { "f", "Fortran" },
+ { "f90", "Fortran" },
+
+ { "s", "Gas" },
+ { "S", "Gas" },
+
+ { ".*%.kid", "Genshi" },
+
+ { "gitignore", "Gitignore" },
+
+ { "vert", "GLSL" },
+ { "frag", "GLSL" },
+ { ".*%.geo", "GLSL" },
+
+ { "plot", "Gnuplot" },
+ { "plt", "Gnuplot" },
+
+ { ".*%.go", "Go" },
+
+ { "hs", "Haskell" },
+ { ".*%.hs", "Haskell" },
+
+ { "htm", "Html" },
+ { "xhtml", "Html" },
+ { "xslt", "Html" },
+
+ { ".*%.hx", "Hx" },
+
+ { "hy", "Hybris" },
+ { "hyb", "Hybris" },
+
+ { "ini", "INI" },
+ { "cfg", "INI" },
+
+ { ".*%.io", "Io" },
+ { "ik", "Ioke" },
+
+ { ".*%.jade", "Jade" },
+
+ { ".*%.Java", "Java" },
+
+ { "ll", "LLVM" },
+
+ { "wlua", "Lua" },
+
+ { "mak", "Make" },
+ { "makefile", "Make" },
+ { "Makefile", "Make" },
+ { "GNUmakefile", "Make" },
+
+ { ".*%.mao", "Make" },
+
+ { "mhtml", "Mason" },
+ { "mc", "Mason" },
+ { ".*%.mi", "Mason" },
+ { "autohandler", "Mason" },
+ { "dhandler", "Mason" },
+
+ { "md", "Markdown" },
+
+ { "m", "Objective C" },
+ { ".*%.m", "Objective C" },
+ { ".*%.j", "Objective J" },
+
+ { "ml", "Ocaml" },
+ { "mli", "Ocaml" },
+ { "mll", "Ocaml" },
+ { "mly", "Ocaml" },
+
+ { "pm", "Perl" },
+ { "pl", "Perl" },
+
+ { "php", "PHP" },
+
+ { "ps", "Postscript" },
+ { "eps", "Postscript" },
+
+ { "pro", "Prolog" },
+ { ".*%.pl", "Prolog" },
+
+ { ".*%.properties", "Properties" },
+
+ { ".*%.py3tb", "Py3tb" },
+ { ".*%.pytb", "Pytb" },
+ { "py", "Python" },
+ { "pyw", "Python" },
+ { "sc", "Python" },
+ { "SConstruct", "Python" },
+ { "SConscript", "Python" },
+ { "tac", "Python" },
+
+ { ".*%.R", "R" },
+
+ { "rb", "Ruby" },
+ { "rbw", "Ruby" },
+ { "RakeFile", "Ruby" },
+ { "rake", "Ruby" },
+ { "gemspec", "Ruby" },
+ { "rbx", "Ruby" },
+ { "duby", "Ruby" },
+
+ { "rs", "rust" },
+
+ { "sql", "SQL" },
+ { ".*%.sql", "SQL" },
+
+ { "txt", "Text" },
+
+ { "ts", "Typescript" },
+
+ { "yml", "Yaml" },
+};
+
+languages.get_name = function (name)
+ if not name or name == "" then
+ return "Unknown";
+ end
+
+ for _, pattern in ipairs(languages.patterns) do
+ if name:match("^" .. pattern[1] .. "$") then
+ return pattern[2];
+ end
+ end
+
+ return string.gsub(name, "^%l", string.upper);
+end
+
+return languages;
diff --git a/lua/markview/parser.lua b/lua/markview/parser.lua
index 4bf9eb6..405f128 100644
--- a/lua/markview/parser.lua
+++ b/lua/markview/parser.lua
@@ -1,30 +1,55 @@
local parser = {};
-- local renderer = require("markview/renderer");
-parser.fiter_lines = function (buffer, from, to, marker)
+parser.fiter_lines = function (buffer, from, to)
local captured_lines = vim.api.nvim_buf_get_lines(buffer, from, to, false);
local filtered_lines = {};
local indexes = {};
local spaces = {};
+ local withinCodeBlock;
+ local parent_marker;
+
local tolarence = 3;
local found = 0;
for l, line in ipairs(captured_lines) do
- if l ~= 1 and line:match(marker) then
- break;
+ if l ~= 1 then
+ if withinCodeBlock ~= true and line:match("^%s*([+%-*])") then
+ break;
+ elseif withinCodeBlock ~= true and line:match("^%s*(%d+%.)") then
+ break;
+ end
end
if found >= tolarence then
break;
end
- local spaces_before = vim.fn.strchars(line:match("(%s*)"));
+ local spaces_before = vim.fn.strchars(line:match("^(%s*)"));
+
+ if line:match("(```)") and withinCodeBlock ~= true then
+ withinCodeBlock = true;
+ goto withinElement;
+ elseif line:match("(```)") and withinCodeBlock == true then
+ withinCodeBlock = false;
+ goto withinElement;
+ elseif withinCodeBlock == true then
+ goto withinElement;
+ end
+
+ if line:match("^%s*([+%-*])") then
+ parent_marker = line:match("^%s*([+%-*])");
+ elseif line:match("^%s*(%d+%.)") then
+ parent_marker = line:match("^%s*(%d+%.)");
+ end
- if not line:match(marker) then
- spaces_before = math.max(0, spaces_before - vim.fn.strchars(marker .. " "));
+ if not line:match("^%s*([+%-*])") and not line:match("^%s*(%d+%.)") and parent_marker then
+ spaces_before = math.max(0, spaces_before - vim.fn.strchars((parent_marker or "") .. " "));
end
+ ::withinElement::
+
table.insert(filtered_lines, line);
table.insert(indexes, l);
table.insert(spaces, spaces_before)
@@ -75,6 +100,16 @@ parser.parsed_content = {};
---@param buffer number
---@param TStree any
parser.md = function (buffer, TStree, from, to)
+ if not parser.cached_conf or not parser.cached_conf.on_injected or parser.cached_conf.on_injected == false then
+ local root = TStree:root();
+ local root_r_start, _, root_r_end, _ = root:range();
+ local buf_lines = vim.api.nvim_buf_line_count(buffer);
+
+ if root_r_start ~= 0 or root_r_end ~= buf_lines then
+ return;
+ end
+ end
+
local scanned_queies = vim.treesitter.query.parse("markdown", [[
((setext_heading) @setext_heading)
@@ -129,23 +164,21 @@ parser.md = function (buffer, TStree, from, to)
col_end = col_end
})
elseif capture_name == "heading" then
+ local parent = capture_node:parent();
+
local heading_txt = capture_node:next_sibling();
- local title = heading_txt ~= nil and vim.treesitter.get_node_text(heading_txt, buffer) or "";
+ local title = heading_txt ~= nil and vim.treesitter.get_node_text(heading_txt, buffer) or nil;
local h_txt_r_start, h_txt_c_start, h_txt_r_end, h_txt_c_end;
- if heading_txt ~= nil then
- h_txt_r_start, h_txt_c_start, h_txt_r_end, h_txt_c_end = heading_txt:range();
- end
-
table.insert(parser.parsed_content, {
node = capture_node,
type = "heading",
level = vim.fn.strchars(capture_text),
+ line = vim.treesitter.get_node_text(parent, buffer),
marker = capture_text,
title = title,
- title_pos = { h_txt_r_start, h_txt_c_start, h_txt_r_end, h_txt_c_end },
row_start = row_start,
row_end = row_end,
@@ -158,6 +191,8 @@ parser.md = function (buffer, TStree, from, to)
local lines = {};
local highest_len = 0;
+ local block_start = vim.api.nvim_buf_get_lines(buffer, row_start, row_start + 1, false)[1];
+
for i = 1,(row_end - row_start) - 2 do
local this_code = vim.api.nvim_buf_get_lines(buffer, row_start + i, row_start + i + 1, false)[1];
local len = vim.fn.strchars(this_code) or 0;
@@ -173,7 +208,7 @@ parser.md = function (buffer, TStree, from, to)
table.insert(parser.parsed_content, {
node = capture_node,
type = "code_block",
- language = not capture_node:named_child(1) and "" or vim.treesitter.get_node_text(capture_node:named_child(1), buffer),
+ language = block_start:match("%s*```(%S*)$") or "",
line_lengths = line_lens,
largest_line = highest_len,
@@ -237,9 +272,23 @@ parser.md = function (buffer, TStree, from, to)
local table_structure = {};
local alignments = {};
+ local line_positions = {};
+
for row in capture_node:iter_children() do
local tmp = {};
+ local row_text = vim.treesitter.get_node_text(row, buffer)
+ local r_row_start, r_col_start, r_row_end, r_col_end = row:range();
+
+ --- Separator gets counted from the start of the line
+ --- So, we will instead count the number of spaces at the start
+ table.insert(line_positions, {
+ row_start = r_row_start,
+ col_start = r_col_start == 0 and vim.fn.strchars(row_text:match("^(%s*)")) or r_col_start,
+ row_end = r_row_end,
+ col_end = r_col_end
+ })
+
if row:type() == "pipe_table_header" then
table.insert(table_structure, "header");
elseif row:type() == "pipe_table_delimiter_row" then
@@ -262,7 +311,7 @@ parser.md = function (buffer, TStree, from, to)
end
end
- table.insert(table_structure, "seperator");
+ table.insert(table_structure, "separator");
elseif row:type() == "pipe_table_row" then
table.insert(table_structure, "content");
else
@@ -281,6 +330,25 @@ parser.md = function (buffer, TStree, from, to)
table.insert(rows, tmp)
end
+ local s_start, s_end;
+
+ -- This is a workaround for hybrid-mode
+ --
+ -- When ,`use_virt_lines` is true the table will take the
+ -- line above it and the line below it.
+ --
+ -- So we must adjust the ranges to match the render.
+ --
+ -- Don't worry, the renderer will use the __r ones in that
+ -- case
+ if parser.cached_conf and parser.cached_conf.tables and parser.cached_conf.tables.use_virt_lines == false then
+ s_start = row_start;
+ s_end = row_end;
+
+ row_start = row_start - 1;
+ row_end = row_end + 1;
+ end
+
table.insert(parser.parsed_content, {
node = capture_node,
type = "table",
@@ -289,22 +357,26 @@ parser.md = function (buffer, TStree, from, to)
rows = rows,
content_alignments = alignments,
+ content_positions = line_positions,
+
+ __r_start = s_start,
+ __r_end = s_end,
row_start = row_start,
row_end = row_end,
col_start = col_start,
- col_end = col_end
+ col_end = col_end,
})
elseif capture_name == "list_item" then
local marker = capture_node:named_child(0);
local marker_text = vim.treesitter.get_node_text(marker, buffer);
local symbol = marker_text:gsub("%s", "");
- local list_lines, lines, spaces = parser.fiter_lines(buffer, row_start, row_end, symbol);
+ local list_lines, lines, spaces = parser.fiter_lines(buffer, row_start, row_end);
local spaces_before_marker = list_lines[1]:match("^(%s*)" .. symbol .. "%s*");
- local c_end, r_end = parser.get_list_end_range(buffer, row_start, row_end, symbol)
+ local c_end, _ = parser.get_list_end_range(buffer, row_start, row_end, symbol)
table.insert(parser.parsed_content, {
node = capture_node,
@@ -366,6 +438,8 @@ parser.md_inline = function (buffer, TStree, from, to)
] @link)
((code_span) @code)
+
+ ((entity_reference) @entity)
]]);
-- The last 2 _ represent the metadata & query
@@ -379,25 +453,42 @@ parser.md_inline = function (buffer, TStree, from, to)
local title = string.match(line ~= nil and line[1] or "", "%b[]%s*(.*)$")
if capture_text == "[-]" then
- table.insert(parser.parsed_content, {
- node = capture_node,
- type = "checkbox",
- state = "pending",
+ for _, extmark in ipairs(parser.parsed_content) do
+ if extmark.type == "list_item" and extmark.row_start == row_start then
+ local start_line = extmark.list_lines[1] or "";
+ local atStart = start_line:match("%-%s+(%[%-%])%s+");
- row_start = row_start,
- row_end = row_end,
+ local chk_start, _ = start_line:find("%[%-%]");
- col_start = col_start,
- col_end = col_end
- })
+ if not atStart or not chk_start or chk_start - 1 ~= col_start then
+ goto invalid;
+ end
+
+ table.insert(parser.parsed_content, {
+ node = capture_node,
+ type = "checkbox",
+ state = "pending",
+
+ row_start = row_start,
+ row_end = row_end,
+
+ col_start = col_start,
+ col_end = col_end
+ });
+
+ break;
+ end
+ ::invalid::
+ end
else
for _, extmark in ipairs(parser.parsed_content) do
if extmark.type == "block_quote" and extmark.row_start == row_start then
-
extmark.callout = string.match(capture_text, "%[!([^%]]+)%]");
extmark.title = title;
- extmark.line_width = vim.fn.strchars(line[1])
+ extmark.line_width = vim.fn.strchars(line[1]);
+
+ break;
end
end
end
@@ -450,6 +541,74 @@ parser.md_inline = function (buffer, TStree, from, to)
col_start = col_start,
col_end = col_end
})
+ elseif capture_name == "entity" then
+ table.insert(parser.parsed_content, {
+ node = capture_node,
+ type = "html_entity",
+
+ text = capture_text,
+
+ row_start = row_start,
+ row_end = row_end,
+
+ col_start = col_start,
+ col_end = col_end
+ })
+ end
+ end
+end
+
+parser.html = function (buffer, TStree, from, to)
+ if not parser.cached_conf or not parser.cached_conf.on_injected or parser.cached_conf.on_injected == false then
+ local root = TStree:root();
+ local root_r_start, _, _, _ = root:range();
+
+ local start_line = vim.api.nvim_buf_get_lines(buffer, root_r_start - 1, root_r_start, false)[1] or "";
+
+ if start_line:match("```") then
+ return;
+ end
+ end
+
+ local scanned_queies = vim.treesitter.query.parse("html", [[
+ ((element) @elem)
+ ]]);
+
+ for capture_id, capture_node, _, _ in scanned_queies:iter_captures(TStree:root(), buffer, from, to) do
+ local capture_name = scanned_queies.captures[capture_id];
+ local capture_text = vim.treesitter.get_node_text(capture_node, buffer);
+ local row_start, col_start, row_end, col_end = capture_node:range();
+
+ if capture_name == "elem" then
+ local node_childs = capture_node:named_child_count();
+
+ local start_tag = capture_node:named_child(0);
+ local end_tag = capture_node:named_child(node_childs - 1);
+
+ if start_tag:type() == "start_tag" and end_tag:type() == "end_tag" and row_start == row_end then
+ local _, ts_col_start, _, ts_col_end = start_tag:range();
+ local _, te_col_start, _, te_col_end = end_tag:range();
+
+ table.insert(parser.parsed_content, {
+ node = capture_node,
+ type = "html_inline",
+
+ tag = vim.treesitter.get_node_text(start_tag, buffer):gsub("[>]", ""):match("%a+"),
+ text = capture_text,
+
+ start_tag_col_start = ts_col_start,
+ start_tag_col_end = ts_col_end,
+
+ end_tag_col_start = te_col_start,
+ end_tag_col_end = te_col_end,
+
+ row_start = row_start,
+ row_end = row_end,
+
+ col_start = col_start,
+ col_end = col_end
+ })
+ end
end
end
end
@@ -458,13 +617,16 @@ end
--- Parsed data is stored as a "view" in renderer.lua
---
---@param buffer number
-parser.init = function (buffer)
+parser.init = function (buffer, config_table)
local root_parser = vim.treesitter.get_parser(buffer);
root_parser:parse(true);
+ if config_table then
+ parser.cached_conf = config_table;
+ end
+
-- Clear the previous contents
parser.parsed_content = {};
- local main_tree_parsed = false;
root_parser:for_each_tree(function (TStree, language_tree)
local tree_language = language_tree:lang();
@@ -473,32 +635,34 @@ parser.init = function (buffer)
parser.md(buffer, TStree)
elseif tree_language == "markdown_inline" then
parser.md_inline(buffer, TStree);
+ elseif tree_language == "html" then
+ parser.html(buffer, TStree);
end
end)
return parser.parsed_content;
end
-parser.parse_range = function (buffer, from, to)
+parser.parse_range = function (buffer, config_table, from, to)
+ if not from or not to then
+ return {};
+ end
+
local root_parser = vim.treesitter.get_parser(buffer);
root_parser:parse(true);
- if (not from or not to) and _G.__markview_render_ranges and _G.__markview_render_ranges[buffer] then
- from = _G.__markview_render_ranges[buffer][1];
- to = _G.__markview_render_ranges[buffer][2];
- end
- --
-- Clear the previous contents
parser.parsed_content = {};
- local main_tree_parsed = false;
root_parser:for_each_tree(function (TStree, language_tree)
local tree_language = language_tree:lang();
if tree_language == "markdown" then
- parser.md(buffer, TStree, from, to)
+ parser.md(buffer, TStree, from, to);
elseif tree_language == "markdown_inline" then
parser.md_inline(buffer, TStree, from, to);
+ elseif tree_language == "html" then
+ parser.html(buffer, TStree, from, to);
end
end)
diff --git a/lua/markview/presets.lua b/lua/markview/presets.lua
index 1c0f2a2..b8774bd 100644
--- a/lua/markview/presets.lua
+++ b/lua/markview/presets.lua
@@ -1,4 +1,360 @@
local presets = {};
+local colors = require("markview.colors");
+
+presets.highlight_groups = {
+ colorful_heading_bg = {
+ ---+ ##code##
+ {
+ -- Heading level 1
+ output = function ()
+ if colors.get_hl_value(0, "DiagnosticOk", "fg") and colors.get_hl_value(0, "Normal", "bg") then
+ local fg = colors.get_hl_value(0, "Normal", "bg");
+ local bg = colors.get_hl_value(0, "DiagnosticOk", "fg");
+
+ local nr = colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading1",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading1Sign",
+ value = {
+ bg = nr,
+ fg = bg,
+
+ default = true
+ }
+ },
+ }
+ else
+ local fg = colors.get_hl_value(0, "Normal", "bg");
+ local bg = vim.o.background == "dark" and "#a6e3a1" or "#40a02b";
+
+ local nr = colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading1",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading1Sign",
+ value = {
+ bg = nr,
+ fg = bg,
+
+ default = true
+ }
+ },
+ }
+ end
+ end
+ },
+ {
+ -- Heading level 2
+ output = function ()
+ if colors.get_hl_value(0, "DiagnosticHint", "fg") and colors.get_hl_value(0, "Normal", "bg") then
+ local fg = colors.get_hl_value(0, "Normal", "bg");
+ local bg = colors.get_hl_value(0, "DiagnosticHint", "fg");
+
+ local nr = colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading2",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading2Sign",
+ value = {
+ bg = nr,
+ fg = bg,
+
+ default = true
+ }
+ },
+ }
+ else
+ local fg = colors.get_hl_value(0, "Normal", "bg");
+ local bg = vim.o.background == "dark" and "#94e2d5" or "#179299";
+
+ local nr = colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading2",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading2Sign",
+ value = {
+ bg = nr,
+ fg = bg,
+
+ default = true
+ }
+ },
+ }
+ end
+ end
+ },
+ {
+ -- Heading level 3
+ output = function ()
+ if colors.get_hl_value(0, "DiagnosticInfo", "fg") and colors.get_hl_value(0, "Normal", "bg") then
+ local fg = colors.get_hl_value(0, "Normal", "bg");
+ local bg = colors.get_hl_value(0, "DiagnosticInfo", "fg");
+
+ local nr = colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading3",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading3Sign",
+ value = {
+ bg = nr,
+ fg = bg,
+
+ default = true
+ }
+ },
+ }
+ else
+ local fg = colors.get_hl_value(0, "Normal", "bg");
+ local bg = vim.o.background == "dark" and "#89dceb" or "#179299";
+
+ local nr = colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading3",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading3Sign",
+ value = {
+ bg = nr,
+ fg = bg,
+
+ default = true
+ }
+ },
+ }
+ end
+ end
+ },
+ {
+ -- Heading level 4
+ output = function ()
+ if colors.get_hl_value(0, "Special", "fg") and colors.get_hl_value(0, "Normal", "bg") then
+ local fg = colors.get_hl_value(0, "Normal", "bg");
+ local bg = colors.get_hl_value(0, "Special", "fg");
+
+ local nr = colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading4",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading4Sign",
+ value = {
+ bg = nr,
+ fg = bg,
+
+ default = true
+ }
+ },
+ }
+ else
+ local fg = colors.get_hl_value(0, "Normal", "bg");
+ local bg = vim.o.background == "dark" and "#f5c2e7" or "#ea76cb";
+
+ local nr = colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading4",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading4Sign",
+ value = {
+ bg = nr,
+ fg = bg,
+
+ default = true
+ }
+ },
+ }
+ end
+ end
+ },
+ {
+ -- Heading level 5
+ output = function ()
+ if colors.get_hl_value(0, "DiagnosticWarn", "fg") and colors.get_hl_value(0, "Normal", "bg") then
+ local fg = colors.get_hl_value(0, "Normal", "bg");
+ local bg = colors.get_hl_value(0, "DiagnosticWarn", "fg");
+
+ local nr = colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading5",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading5Sign",
+ value = {
+ bg = nr,
+ fg = bg,
+
+ default = true
+ }
+ },
+ }
+ else
+ local fg = colors.get_hl_value(0, "Normal", "bg");
+ local bg = vim.o.background == "dark" and "#F9E3AF" or "#DF8E1D";
+
+ local nr = colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading5",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading5Sign",
+ value = {
+ bg = nr,
+ fg = bg,
+
+ default = true
+ }
+ },
+ }
+ end
+ end
+ },
+ {
+ -- Heading level 6
+ output = function ()
+ if colors.get_hl_value(0, "DiagnosticError", "fg") and colors.get_hl_value(0, "Normal", "bg") then
+ local fg = colors.get_hl_value(0, "Normal", "bg");
+ local bg = colors.get_hl_value(0, "DiagnosticError", "fg");
+
+ local nr = colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading6",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading6Sign",
+ value = {
+ bg = nr,
+ fg = bg,
+
+ default = true
+ }
+ },
+ }
+ else
+ local fg = colors.get_hl_value(0, "Normal", "bg");
+ local bg = vim.o.background == "dark" and "#F38BA8" or "#D20F39";
+
+ local nr = colors.get_hl_value(0, "LineNr", "bg");
+
+ return {
+ {
+ group_name = "Heading6",
+ value = {
+ bg = bg,
+ fg = fg,
+
+ default = true
+ }
+ },
+ {
+ group_name = "Heading6Sign",
+ value = {
+ bg = nr,
+ fg = bg,
+
+ default = true
+ }
+ },
+ }
+ end
+ end
+ },
+ ---_
+ }
+};
presets.headings = {
glow = {
@@ -10,7 +366,7 @@ presets.headings = {
heading_1 = {
style = "label",
- hl = "MarkviewCol1Inv",
+ hl = "MarkviewHeading1",
padding_left = " ",
padding_right = " "
@@ -21,13 +377,26 @@ presets.headings = {
enable = true,
shift_width = 0,
+ setext_1 = {
+ style = "github",
+
+ icon = " ", hl = "MarkviewHeading1",
+ underline = "━"
+ },
+ setext_2 = {
+ style = "github",
+
+ icon = " ", hl = "MarkviewHeading2",
+ underline = "─"
+ },
+
heading_1 = {
style = "label",
padding_left = " ",
padding_right = " ",
- hl = "MarkviewCol1Inv"
+ hl = "MarkviewHeading1"
},
heading_2 = {
style = "label",
@@ -35,7 +404,7 @@ presets.headings = {
padding_left = " ",
padding_right = " ",
- hl = "MarkviewCol2Inv"
+ hl = "MarkviewHeading2"
},
heading_3 = {
style = "label",
@@ -43,7 +412,7 @@ presets.headings = {
padding_left = " ",
padding_right = " ",
- hl = "MarkviewCol3Inv"
+ hl = "MarkviewHeading3"
},
heading_4 = {
style = "label",
@@ -51,7 +420,7 @@ presets.headings = {
padding_left = " ",
padding_right = " ",
- hl = "MarkviewCol4Inv"
+ hl = "MarkviewHeading4"
},
heading_5 = {
style = "label",
@@ -59,7 +428,7 @@ presets.headings = {
padding_left = " ",
padding_right = " ",
- hl = "MarkviewCol5Inv"
+ hl = "MarkviewHeading5"
},
heading_6 = {
style = "label",
@@ -67,7 +436,7 @@ presets.headings = {
padding_left = " ",
padding_right = " ",
- hl = "MarkviewCol6Inv"
+ hl = "MarkviewHeading6"
},
},
decorated_labels = {
@@ -82,9 +451,9 @@ presets.headings = {
padding_right = " ",
corner_right = "",
- corner_right_hl = "MarkviewCol1Fg",
+ corner_right_hl = "MarkviewHeading1Sign",
- hl = "MarkviewCol1Inv"
+ hl = "MarkviewHeading1"
},
heading_2 = {
style = "label",
@@ -93,9 +462,9 @@ presets.headings = {
padding_right = " ",
corner_right = "",
- corner_right_hl = "MarkviewCol2Fg",
+ corner_right_hl = "MarkviewHeading2",
- hl = "MarkviewCol2Inv"
+ hl = "MarkviewHeading2Sign"
},
heading_3 = {
style = "label",
@@ -104,9 +473,9 @@ presets.headings = {
padding_right = " ",
corner_right = "",
- corner_right_hl = "MarkviewCol3Fg",
+ corner_right_hl = "MarkviewHeading3",
- hl = "MarkviewCol3Inv"
+ hl = "MarkviewHeading3Sign"
},
heading_4 = {
style = "label",
@@ -115,9 +484,9 @@ presets.headings = {
padding_right = " ",
corner_right = "",
- corner_right_hl = "MarkviewCol4Fg",
+ corner_right_hl = "MarkviewHeading4",
- hl = "MarkviewCol4Inv"
+ hl = "MarkviewHeading4Sign"
},
heading_5 = {
style = "label",
@@ -126,9 +495,9 @@ presets.headings = {
padding_right = " ",
corner_right = "",
- corner_right_hl = "MarkviewCol5Fg",
+ corner_right_hl = "MarkviewHeading5",
- hl = "MarkviewCol5Inv"
+ hl = "MarkviewHeading5Sign"
},
heading_6 = {
style = "label",
@@ -137,9 +506,9 @@ presets.headings = {
padding_right = " ",
corner_right = "",
- corner_right_hl = "MarkviewCol6Fg",
+ corner_right_hl = "MarkviewHeading6",
- hl = "MarkviewCol6Inv"
+ hl = "MarkviewHeading6Sign"
},
},
@@ -151,32 +520,32 @@ presets.headings = {
heading_1 = {
style = "simple",
- hl = "MarkviewCol1"
+ hl = "MarkviewHeading1"
},
heading_2 = {
style = "simple",
- hl = "MarkviewCol2"
+ hl = "MarkviewHeading2"
},
heading_3 = {
style = "simple",
- hl = "MarkviewCol3"
+ hl = "MarkviewHeading3"
},
heading_4 = {
style = "simple",
- hl = "MarkviewCol4"
+ hl = "MarkviewHeading4"
},
heading_5 = {
style = "simple",
- hl = "MarkviewCol5"
+ hl = "MarkviewHeading5"
},
heading_6 = {
style = "simple",
- hl = "MarkviewCol6"
+ hl = "MarkviewHeading6"
},
},
simple_no_marker = {
@@ -191,37 +560,37 @@ presets.headings = {
style = "icon",
icon = " ",
- hl = "MarkviewCol1"
+ hl = "MarkviewHeading1"
},
heading_2 = {
style = "icon",
icon = " ",
- hl = "MarkviewCol2"
+ hl = "MarkviewHeading2"
},
heading_3 = {
style = "icon",
icon = " ",
- hl = "MarkviewCol3"
+ hl = "MarkviewHeading3"
},
heading_4 = {
style = "icon",
icon = " ",
- hl = "MarkviewCol4"
+ hl = "MarkviewHeading4"
},
heading_5 = {
style = "icon",
icon = " ",
- hl = "MarkviewCol5"
+ hl = "MarkviewHeading5"
},
heading_6 = {
style = "icon",
icon = " ",
- hl = "MarkviewCol6"
+ hl = "MarkviewHeading6"
},
},
};
@@ -260,11 +629,11 @@ presets.tables = {
},
-- This is a required property
hl = {
- nil, "MarkviewCol1Fg", nil, nil,
+ nil, "MarkviewTableBorder", nil, nil,
nil, nil, nil, nil,
nil, nil, nil, nil,
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg",
+ "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder",
},
use_virt_lines = false
@@ -282,11 +651,11 @@ presets.tables = {
"╼", "╾", "╴", "╶"
},
hl = {
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg",
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg",
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg",
+ "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder",
+ "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder",
+ "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder",
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg"
+ "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder"
},
use_virt_lines = false
@@ -304,11 +673,11 @@ presets.tables = {
"╼", "╾", "╴", "╶"
},
hl = {
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg",
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg",
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg",
+ "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder",
+ "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder",
+ "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder",
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg"
+ "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder"
},
use_virt_lines = false
@@ -327,11 +696,11 @@ presets.tables = {
"━", "━", "━", "━"
},
hl = {
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg",
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg",
- "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg", "MarkviewCol1Fg",
+ "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder",
+ "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder",
+ "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder", "MarkviewTableBorder",
- "MarkviewCol3Fg", "MarkviewCol4Fg", "MarkviewCol6Fg", "MarkviewCol6Fg"
+ "MarkviewTableAlignLeft", "MarkviewTableAlignRight", "MarkviewTableAlignCenter", "MarkviewTableAlignCenter"
},
use_virt_lines = false
diff --git a/lua/markview/renderer.lua b/lua/markview/renderer.lua
index a963c41..8a77231 100644
--- a/lua/markview/renderer.lua
+++ b/lua/markview/renderer.lua
@@ -1,7 +1,8 @@
local renderer = {};
local devicons = require("nvim-web-devicons");
-local utils = require("markview.utils");
+local entites = require("markview.entites");
+local languages = require("markview.languages");
_G.__markview_views = {};
@@ -66,7 +67,9 @@ local display_width = function (text, config)
local d_width = vim.fn.strchars(text);
local inl_conf = config.inline_codes;
- for inline_code in text:gmatch("`([^`]+)`") do
+ local final_string = text;
+
+ for inline_code in final_string:gmatch("`([^`]+)`") do
d_width = d_width - (vim.fn.strchars("`" .. inline_code .. "`"));
if inl_conf ~= nil and inl_conf.enable ~= false then
@@ -79,13 +82,24 @@ local display_width = function (text, config)
inl_conf.padding_right or "",
inl_conf.corner_right or ""
}));
+
+ final_string = final_string:gsub("`" .. inline_code .. "`", table.concat({
+ inl_conf.corner_left or "",
+ inl_conf.padding_left or "",
+
+ inline_code or "",
+
+ inl_conf.padding_right or "",
+ inl_conf.corner_right or ""
+ }));
end
end
- local lnk_conf = config.links ~= nil and config.links.inline_links or nil;
+ local lnk_conf = config.links ~= nil and config.links.hyperlinks or nil;
local img_conf = config.links ~= nil and config.links.images or nil;
+ local email_conf = config.links ~= nil and config.links.emails or nil;
- for img_identifier, link, address in text:gmatch("(!?)%[([^%]]+)%]%(([^%)]+)%)") do
+ for img_identifier, link, address in final_string:gmatch("(!?)%[([^%]]+)%]%(([^%)]+)%)") do
if img_identifier ~= "" then
d_width = d_width - vim.fn.strchars("![" .. "](" .. address .. ")");
@@ -97,6 +111,15 @@ local display_width = function (text, config)
img_conf.padding_right or "",
img_conf.corner_right or ""
}));
+
+ final_string = final_string:gsub("!%[" .. link .. "%]%(" .. address .. "%)", table.concat({
+ img_conf.corner_left or "",
+ img_conf.padding_left or "",
+ img_conf.icon or "",
+ link,
+ img_conf.padding_right or "",
+ img_conf.corner_right or ""
+ }));
end
else
d_width = d_width - vim.fn.strchars("[" .. "](" .. address .. ")");
@@ -109,16 +132,25 @@ local display_width = function (text, config)
lnk_conf.padding_right or "",
lnk_conf.corner_right or ""
}));
+
+ final_string = final_string:gsub("%[" .. link .. "%]%(" .. address .. "%)", table.concat({
+ lnk_conf.corner_left or "",
+ lnk_conf.padding_left or "",
+ lnk_conf.icon or "",
+ link,
+ lnk_conf.padding_right or "",
+ lnk_conf.corner_right or ""
+ }));
end
end
end
- for str_a, str_b in text:gmatch("([*]+)[^*]+([*]+)") do
+ for str_a, internal, str_b in final_string:gmatch("([*]+)([^*]+)([*]+)") do
local min_signs = vim.fn.strchars(str_a) > vim.fn.strchars(str_b) and vim.fn.strchars(str_a) or vim.fn.strchars(str_b);
- local start_pos, _ = text:find("([*]+)[^*]+([*]+)");
+ local start_pos, _ = final_string:find("([*]+)[^*]+([*]+)");
- local c_before = text:sub(start_pos - 1, start_pos - 1);
+ local c_before = final_string:sub(start_pos - 1, start_pos - 1);
-- local c_after = text:sub(end_pos + 1, end_pos + 1);
-- Needs more flexibility
@@ -132,14 +164,123 @@ local display_width = function (text, config)
if a == b then
d_width = d_width - 2;
+
+ final_string = final_string:gsub(a .. internal .. b, internal);
end
end
::invalid::
end
+ for username, domain, tdl in final_string:gmatch("<([%w._%+-]+)@([%w.-]+)%.([%w.-]+)>") do
+ d_width = d_width - vim.fn.strchars("<" .. ">");
+
+ if email_conf ~= nil and email_conf.enable ~= false then
+ d_width = d_width + vim.fn.strchars(table.concat({
+ email_conf.corner_left or "",
+ email_conf.padding_left or "",
+ email_conf.icon or "",
+ email_conf.padding_right or "",
+ email_conf.corner_right or ""
+ }));
+
+ final_string = final_string:gsub("<" .. username .. "@" .. domain .. "." .. tdl .. ">", table.concat({
+ email_conf.corner_left or "",
+ email_conf.padding_left or "",
+ email_conf.icon or "",
+
+ username, "@", domain, ".", tdl,
+
+ email_conf.padding_right or "",
+ email_conf.corner_right or ""
+ }));
+ end
+ end
+
+ local tmp_string = final_string;
+ local iterations = 1;
+
+ local html_conf = config.html;
+
+ while tmp_string:match("<([^>]+)>") do
+ -- This shouldn't run so many times
+ if not html_conf or html_conf.enable == false then
+ break;
+ elseif not html_conf.tags or html_conf.tags.enable == false then
+ break;
+ elseif iterations > 10 then
+ break;
+ else
+ iterations = iterations + 1;
+ end
+
+ local start_tag = tmp_string:match("<([^>]+)>");
+ local s_tag_start, _ = tmp_string:find("<([^>]+)>");
+
+ local filtered_tag = start_tag:match("%a+");
+
+ -- No close tag
+ if not tmp_string:match("" .. filtered_tag .. ">") then
+ goto invalid;
+ end
+
+ local end_tag = tmp_string:match("(" .. filtered_tag .. ")>");
+ local e_tag_start, _ = tmp_string:find("" .. filtered_tag .. ">");
+
+ -- Close tag before opening tag
+ if e_tag_start < s_tag_start then
+ goto invalid;
+ end
+
+ local tag_conf = html_conf.tags;
+ local conf = tag_conf.default or {};
+
+ if tag_conf.configs and tag_conf.configs[string.lower(filtered_tag)] then
+ conf = tag_conf.configs[string.lower(filtered_tag)]
+ end
+
+ local internal_text = tmp_string:match("<" .. start_tag .. ">(.-)" .. end_tag .. ">") or "";
+
+ -- Tag isn't concealed
+ if conf.conceal ~= false then
+ final_string = final_string:gsub("<" .. start_tag .. ">" .. internal_text .. "" .. end_tag .. ">", internal_text)
+ d_width = d_width - vim.fn.strchars("<" .. start_tag .. ">" .. "" .. end_tag .. ">", internal_text);
+ end
+
+ tmp_string = tmp_string:gsub("<" .. start_tag .. ">" .. internal_text .. "" .. end_tag .. ">", internal_text)
+
+ ::invalid::
+ end
+
+ for entity_name, semicolon in final_string:gmatch("&([%a%d]+)(;?)") do
+ if not html_conf or html_conf.enable == false then
+ break;
+ elseif not html_conf.entites or html_conf.entites.enable == false then
+ break;
+ end
+
+ local entity = entites.get(entity_name);
+
+ if not entity then
+ goto invalid;
+ end
- return d_width, vim.fn.strchars(text);
+ if semicolon then
+ final_string = final_string:gsub("&" .. entity_name .. ";", entity);
+
+ d_width = d_width - vim.fn.strchars("&" .. entity_name .. ";");
+ d_width = d_width + vim.fn.strdisplaywidth(entity);
+ else
+ final_string = final_string:gsub("&" .. entity_name, entity);
+
+ d_width = d_width - vim.fn.strchars("&" .. entity_name);
+ d_width = d_width + vim.fn.strdisplaywidth(entity);
+ end
+
+ ::invalid::
+ end
+
+ return d_width, vim.fn.strchars(text), final_string;
end
@@ -150,47 +291,58 @@ end
local table_header = function (buffer, content, config_table)
local tbl_conf = config_table.tables;
+ local row_start = content.__r_start or content.row_start;
+ local col_start = content.col_start;
+
local curr_col = 0;
local curr_tbl_col = 1;
local virt_txt = {};
+ if content.content_positions and content.content_positions[1] then
+ table.insert(virt_txt, { string.rep(" ", content.content_positions[1].col_start) })
+ col_start = content.content_positions[1].col_start;
+ end
+
for index, col in ipairs(content.rows[1]) do
if index == 1 then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_start, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start, col_start, {
virt_text_pos = "inline",
virt_text = {
{ tbl_conf.text[6], set_hl(tbl_conf.hl[6]) }
},
- end_col = content.col_start + 1,
+ end_col = col_start + 1,
conceal = ""
});
table.insert(virt_txt, { tbl_conf.text[1], set_hl(tbl_conf.hl[1]) })
curr_col = curr_col + 1
elseif index == #content.rows[1] then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_start + curr_col, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start, col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ tbl_conf.text[6], set_hl(tbl_conf.hl[6]) }
},
- end_col = content.col_start + curr_col + 1,
+ end_col = col_start + curr_col + 1,
conceal = ""
});
table.insert(virt_txt, { tbl_conf.text[3], set_hl(tbl_conf.hl[3]) })
if config_table.tables.use_virt_lines == true then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_start, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start, 0, {
virt_lines_above = true,
virt_lines = {
virt_txt
}
});
- elseif content.row_start > 0 then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start - 1, content.col_start, {
+ elseif row_start > 0 then
+ -- BUG: Nearby tables can cause text to overlap
+ vim.api.nvim_buf_clear_namespace(buffer, renderer.namespace, row_start - 1, row_start);
+
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start - 1, 0, {
virt_text_pos = "inline",
virt_text = virt_txt
});
@@ -198,13 +350,13 @@ local table_header = function (buffer, content, config_table)
curr_col = curr_col + 1
elseif col == "|" then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_start + curr_col, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start, col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ tbl_conf.text[6], set_hl(tbl_conf.hl[6]) }
},
- end_col = content.col_start + curr_col + 1,
+ end_col = col_start + curr_col + 1,
conceal = ""
});
@@ -216,14 +368,14 @@ local table_header = function (buffer, content, config_table)
if width < actual_width then
if align == "left" then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_start + curr_col + width + 1, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start, col_start + curr_col + vim.fn.strchars(col), {
virt_text_pos = "inline",
virt_text = {
{ string.rep(" ", (actual_width - width)) }
}
});
elseif align == "right" then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_start, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start, col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ string.rep(" ", (actual_width - width)) }
@@ -232,14 +384,14 @@ local table_header = function (buffer, content, config_table)
else
local before, after = math.floor((actual_width - width) / 2), math.ceil((actual_width - width) / 2);
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_start + curr_col + width + 1, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start, col_start + curr_col + vim.fn.strchars(col), {
virt_text_pos = "inline",
virt_text = {
{ string.rep(" ", after) }
}
});
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_start + curr_col, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start, col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ string.rep(" ", before) }
@@ -255,7 +407,7 @@ local table_header = function (buffer, content, config_table)
end
end
---- Renderer for table seperator
+--- Renderer for table separator
---@param buffer number
---@param content any
---@param user_config markview.config
@@ -263,42 +415,49 @@ end
local table_seperator = function (buffer, content, user_config, r_num)
local tbl_conf = user_config.tables;
+ local row_start = content.__r_start or content.row_start;
+ local col_start = content.col_start;
+
local curr_col = 0;
local curr_tbl_col = 1;
+ if content.content_positions and content.content_positions[r_num] then
+ col_start = content.content_positions[r_num].col_start;
+ end
+
for index, col in ipairs(content.rows[r_num]) do
if index == 1 then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + (r_num - 1), content.col_start, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start + (r_num - 1), col_start, {
virt_text_pos = "inline",
virt_text = {
{ tbl_conf.text[5], set_hl(tbl_conf.hl[5]) }
},
- end_col = content.col_start + 1,
+ end_col = col_start + 1,
conceal = ""
});
curr_col = curr_col + 1;
elseif index == #content.rows[1] then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + (r_num - 1), content.col_start + curr_col, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start + (r_num - 1), col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ tbl_conf.text[7], set_hl(tbl_conf.hl[7]) }
},
- end_col = content.col_start + curr_col + 1,
+ end_col = col_start + curr_col + 1,
conceal = ""
});
curr_col = curr_col + 1;
elseif col == "|" then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + (r_num - 1), content.col_start + curr_col, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start + (r_num - 1), col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ tbl_conf.text[8], set_hl(tbl_conf.hl[8]) }
},
- end_col = content.col_start + curr_col + 1,
+ end_col = col_start + curr_col + 1,
conceal = ""
});
@@ -308,29 +467,29 @@ local table_seperator = function (buffer, content, user_config, r_num)
if col:match(":") then
if align == "left" then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + (r_num - 1), content.col_start + curr_col, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start + (r_num - 1), col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ tbl_conf.text[13], set_hl(tbl_conf.hl[13]) },
{ string.rep(tbl_conf.text[2], vim.fn.strchars(col) - 1), set_hl(tbl_conf.hl[2]) }
},
- end_col = content.col_start + curr_col + vim.fn.strchars(col) + 1,
+ end_col = col_start + curr_col + vim.fn.strchars(col) + 1,
conceal = ""
});
elseif align == "right" then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + (r_num - 1), content.col_start + curr_col, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start + (r_num - 1), col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ string.rep(tbl_conf.text[2], vim.fn.strchars(col) - 1), set_hl(tbl_conf.hl[2]) },
{ tbl_conf.text[14], set_hl(tbl_conf.hl[14]) }
},
- end_col = content.col_start + curr_col + vim.fn.strchars(col) + 1,
+ end_col = col_start + curr_col + vim.fn.strchars(col) + 1,
conceal = ""
});
elseif align == "center" then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + (r_num - 1), content.col_start + curr_col, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start + (r_num - 1), col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ tbl_conf.text[15], set_hl(tbl_conf.hl[15]) },
@@ -338,18 +497,18 @@ local table_seperator = function (buffer, content, user_config, r_num)
{ tbl_conf.text[16], set_hl(tbl_conf.hl[16]) }
},
- end_col = content.col_start + curr_col + vim.fn.strchars(col) + 1,
+ end_col = col_start + curr_col + vim.fn.strchars(col) + 1,
conceal = ""
});
end
else
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + (r_num - 1), content.col_start + curr_col, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_start + (r_num - 1), col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ string.rep(tbl_conf.text[2], vim.fn.strchars(col)), set_hl(tbl_conf.hl[8]) }
},
- end_col = content.col_start + curr_col + vim.fn.strchars(col) + 1,
+ end_col = col_start + curr_col + vim.fn.strchars(col) + 1,
conceal = ""
});
end
@@ -367,47 +526,55 @@ end
local table_footer = function (buffer, content, config_table)
local tbl_conf = config_table.tables;
+ local row_end = content.__r_end or content.row_end;
+ local col_start = content.col_start;
+
local curr_col = 0;
local curr_tbl_col = 1;
local virt_txt = {};
+ if content.content_positions and content.content_positions[#content.content_positions] then
+ table.insert(virt_txt, { string.rep(" ", content.content_positions[#content.content_positions].col_start) })
+ col_start = content.content_positions[#content.content_positions].col_start;
+ end
+
for index, col in ipairs(content.rows[#content.rows]) do
if index == 1 then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_end - 1, content.col_start, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_end - 1, col_start, {
virt_text_pos = "inline",
virt_text = {
{ tbl_conf.text[6], set_hl(tbl_conf.hl[6]) }
},
- end_col = content.col_start + 1,
+ end_col = col_start + 1,
conceal = ""
});
table.insert(virt_txt, { tbl_conf.text[9], set_hl(tbl_conf.hl[9]) })
curr_col = curr_col + 1
- elseif index == #content.rows[1] then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_end - 1, content.col_start + curr_col, {
+ elseif index == #content.rows[#content.rows] then
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_end - 1, col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ tbl_conf.text[6], set_hl(tbl_conf.hl[6]) }
},
- end_col = content.col_start + curr_col + 1,
+ end_col = col_start + curr_col + 1,
conceal = ""
});
table.insert(virt_txt, { tbl_conf.text[11], set_hl(tbl_conf.hl[11]) })
if config_table.tables.use_virt_lines == true then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_end - 1, content.col_start, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_end - 1, 0, {
virt_lines_above = false,
virt_lines = {
virt_txt
}
});
- elseif content.row_start > 0 then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_end, content.col_start, {
+ elseif content.row_start < vim.api.nvim_buf_line_count(buffer) then
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_end, 0, {
virt_text_pos = "inline",
virt_text = virt_txt
});
@@ -415,13 +582,13 @@ local table_footer = function (buffer, content, config_table)
curr_col = curr_col + 1
elseif col == "|" then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_end - 1, content.col_start + curr_col, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_end - 1, col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ tbl_conf.text[6], set_hl(tbl_conf.hl[6]) }
},
- end_col = content.col_start + curr_col + 1,
+ end_col = col_start + curr_col + 1,
conceal = ""
});
@@ -433,14 +600,14 @@ local table_footer = function (buffer, content, config_table)
if width < actual_width then
if align == "left" then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_end - 1, content.col_start + curr_col + width + 1, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_end - 1, col_start + curr_col + vim.fn.strchars(col), {
virt_text_pos = "inline",
virt_text = {
{ string.rep(" ", (actual_width - width)) }
}
});
elseif align == "right" then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_end - 1, content.col_start, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_end - 1, col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ string.rep(" ", (actual_width - width)) }
@@ -449,14 +616,14 @@ local table_footer = function (buffer, content, config_table)
else
local before, after = math.floor((actual_width - width) / 2), math.ceil((actual_width - width) / 2);
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_end - 1, content.col_start + curr_col + width + 1, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_end - 1, col_start + curr_col + vim.fn.strchars(col), {
virt_text_pos = "inline",
virt_text = {
{ string.rep(" ", after) }
}
});
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_end - 1, content.col_start + curr_col, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, row_end - 1, col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ string.rep(" ", before) }
@@ -480,42 +647,48 @@ end
local table_content = function (buffer, content, config_table, r_num)
local tbl_conf = config_table.tables;
+ local col_start = content.col_start;
+
local curr_col = 0;
local curr_tbl_col = 1;
+ if content.content_positions and content.content_positions[r_num] then
+ col_start = content.content_positions[r_num].col_start;
+ end
+
for index, col in ipairs(content.rows[r_num]) do
if index == 1 then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + r_num - 1, content.col_start, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + r_num - 1, col_start, {
virt_text_pos = "inline",
virt_text = {
{ tbl_conf.text[6], set_hl(tbl_conf.hl[6]) }
},
- end_col = content.col_start + 1,
+ end_col = col_start + 1,
conceal = ""
});
curr_col = curr_col + 1
elseif index == #content.rows[1] then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + r_num - 1, content.col_start + curr_col, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + r_num - 1, col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ tbl_conf.text[6], set_hl(tbl_conf.hl[6]) }
},
- end_col = content.col_start + curr_col + 1,
+ end_col = col_start + curr_col + 1,
conceal = ""
});
curr_col = curr_col + 1
elseif col == "|" then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + r_num - 1, content.col_start + curr_col, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + r_num - 1, col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ tbl_conf.text[6], set_hl(tbl_conf.hl[6]) }
},
- end_col = content.col_start + curr_col + 1,
+ end_col = col_start + curr_col + 1,
conceal = ""
});
@@ -526,14 +699,14 @@ local table_content = function (buffer, content, config_table, r_num)
if width < actual_width then
if align == "left" then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + r_num - 1, content.col_start + curr_col + width + 1, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + r_num - 1, col_start + curr_col + vim.fn.strchars(col), {
virt_text_pos = "inline",
virt_text = {
{ string.rep(" ", (actual_width - width)) }
}
});
elseif align == "right" then
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + r_num - 1, content.col_start, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + r_num - 1, col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ string.rep(" ", (actual_width - width)) }
@@ -542,14 +715,14 @@ local table_content = function (buffer, content, config_table, r_num)
else
local before, after = math.floor((actual_width - width) / 2), math.ceil((actual_width - width) / 2);
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + r_num - 1, content.col_start + curr_col + width + 1, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + r_num - 1, col_start + curr_col + vim.fn.strchars(col), {
virt_text_pos = "inline",
virt_text = {
{ string.rep(" ", after) }
}
});
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + r_num - 1, content.col_start + curr_col, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + r_num - 1, col_start + curr_col, {
virt_text_pos = "inline",
virt_text = {
{ string.rep(" ", before) }
@@ -573,7 +746,7 @@ renderer.views = {};
---@param content any
---@param config markview.render_config.headings
renderer.render_headings = function (buffer, content, config)
- if config.enable == false then
+ if not config or config.enable == false then
return;
end
@@ -581,6 +754,11 @@ renderer.render_headings = function (buffer, content, config)
local conf = config["heading_" .. content.level] or {};
local shift = config.shift_width or vim.bo[buffer].shiftwidth;
+ -- Do not proceed if config doesn't exist for a heading
+ if not conf then
+ return;
+ end
+
if conf.style == "simple" then
-- Adds a simple background
vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_start, {
@@ -589,85 +767,76 @@ renderer.render_headings = function (buffer, content, config)
hl_mode = "combine"
});
elseif conf.style == "label" then
- -- FIX: Make headings editable
- local add_spaces = vim.fn.strchars(table.concat({
- string.rep(conf.shift_char or " ", shift * (content.level - 1)),
- conf.corner_left or "",
- conf.padding_left or "",
- conf.icon or "",
- }));
-
- -- Adds icons, seperators, paddings etc
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, 0, {
- virt_text_pos = "overlay",
+ local conceal_start = string.match(content.line, "^[#]+(%s*)");
+ local line_length = vim.fn.strchars(content.line);
+
+ -- Heading rules
+ -- 1. Must start at the first column
+ -- 2. Must have 1 space between the marker and the title
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_start, {
+ virt_text_pos = "inline",
virt_text = {
{ string.rep(conf.shift_char or " ", shift * (content.level - 1)), conf.shift_hl },
{ conf.corner_left or "", set_hl(conf.corner_left_hl) or set_hl(conf.hl) },
{ conf.padding_left or "", set_hl(conf.padding_left_hl) or set_hl(conf.hl) },
- { conf.icon or "", set_hl(conf.icon_hl) or set_hl(conf.hl) },
- { conf.text or content.title or "", set_hl(conf.text_hl) or set_hl(conf.hl) },
- { conf.padding_right or "", set_hl(conf.padding_right_hl) or set_hl(conf.hl) },
- { conf.corner_right or "", set_hl(conf.corner_right_hl) or set_hl(conf.hl) },
+ { conf.icon or "", set_hl(conf.icon_hl) or set_hl(conf.hl) }
},
- sign_text = conf.sign, sign_hl_group = set_hl(conf.sign_hl) or set_hl(conf.hl),
-
+ sign_text = conf.sign, sign_hl_group = set_hl(conf.sign_hl),
hl_mode = "combine",
- })
- -- Add extra spaces to match the virtual text
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, 0, {
+ end_col = content.level + vim.fn.strchars(conceal_start),
+ conceal = ""
+ });
+
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, line_length, {
virt_text_pos = "inline",
- virt_text = { { string.rep(" ", add_spaces) } },
+ virt_text = {
+ { conf.padding_right or "", set_hl(conf.padding_right_hl) or set_hl(conf.hl) },
+ { conf.corner_right or "", set_hl(conf.corner_right_hl) or set_hl(conf.hl) }
+ },
- end_col = content.title_pos[2] or content.col_end,
- conceal = ""
+ hl_mode = "combine"
});
+
+ vim.api.nvim_buf_add_highlight(buffer, renderer.namespace, set_hl(conf.hl), content.row_start, 0, line_length);
elseif conf.style == "icon" then
- -- FIX: Make headings editable
- local add_spaces = vim.fn.strchars(table.concat({
- string.rep(conf.shift_char or " ", shift * (content.level - 1)),
- conf.icon or ""
- }));
-
- -- Adds simple icons with paddings
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, 0, {
- virt_text_pos = "overlay",
+ local conceal_start = string.match(content.line, "^[#]+(%s*)");
+
+ -- Heading rules
+ -- 1. Must start at the first column
+ -- 2. Must have 1 space between the marker and the title
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_start, {
+ virt_text_pos = "inline",
virt_text = {
{ string.rep(conf.shift_char or " ", shift * (content.level - 1)), set_hl(conf.shift_hl) },
{ conf.icon or "", set_hl(conf.icon_hl) or set_hl(conf.hl) },
- { conf.text or content.title or "", set_hl(conf.text_hl) or set_hl(conf.hl) },
},
+ sign_text = conf.sign, sign_hl_group = set_hl(conf.sign_hl),
+ line_hl_group = set_hl(conf.hl),
hl_mode = "combine",
- })
- -- Add extra spaces to match the virtual text
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, 0, {
- virt_text_pos = "inline",
- virt_text = { { string.rep(" ", add_spaces) } },
-
- end_col = content.title_pos[2] or content.col_end,
+ end_col = content.level + vim.fn.strchars(conceal_start),
conceal = ""
});
-
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, 0, {
- line_hl_group = set_hl(conf.hl),
- sign_text = conf.sign, sign_hl_group = set_hl(conf.sign_hl),
- });
end
end
renderer.render_headings_s = function (buffer, content, config)
- if config.enable == false then
+ if not config or config.enable == false then
return;
end
---@type markview.render_config.headings.h
local conf = content.marker:match("=") and config["setext_1"] or config["setext_2"];
- local shift = config.shift_width or vim.bo[buffer].shiftwidth;
+
+ -- Do not proceed if setext headings don't have configuraton
+ if not conf then
+ return;
+ end
if conf.style == "simple" then
-- Adds a simple background
@@ -724,7 +893,7 @@ end
---@param content any
---@param config_table markview.render_config.code_blocks
renderer.render_code_blocks = function (buffer, content, config_table)
- if config_table == nil or config_table.enable == false then
+ if not config_table or config_table.enable == false then
return;
end
@@ -790,27 +959,32 @@ renderer.render_code_blocks = function (buffer, content, config_table)
local icon, hl = devicons.get_icon(nil, language, { default = true });
local block_length = content.largest_line;
+ local languageName;
+
if config_table.language_names ~= nil then
for _, lang in ipairs(config_table.language_names) do
if language == lang[1] then
- language = lang[2];
- break;
+ languageName = lang[2];
+ goto nameFound;
end
end
end
+ languageName = languages.get_name(language)
+ ::nameFound::
+
if type(config_table.min_width) == "number" and config_table.min_width > block_length then
block_length = config_table.min_width
end
- local lang_width = vim.fn.strchars(icon .. " " .. language .. " ");
+ local lang_width = vim.fn.strchars(" " .. icon .. " " .. languageName .. " ");
if config_table.language_direction == nil or config_table.language_direction == "left" then
vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_start + 3 + vim.fn.strlen(content.language), {
virt_text_pos = config_table.position or "inline",
virt_text = {
- { icon .. " ", set_hl(hl) },
- { language .. " ", set_hl(config_table.name_hl) or set_hl(hl) },
+ { " " .. icon .. " ", set_hl(hl) },
+ { languageName .. " ", set_hl(config_table.name_hl) or set_hl(hl) },
{ string.rep(config_table.pad_char or " ", block_length - lang_width + ((config_table.pad_amount or 1) * 2)), set_hl(config_table.hl) },
},
@@ -824,8 +998,8 @@ renderer.render_code_blocks = function (buffer, content, config_table)
virt_text_pos = config_table.position or "inline",
virt_text = {
{ string.rep(config_table.pad_char or " ", block_length - lang_width + ((config_table.pad_amount or 1) * 2)), set_hl(config_table.hl) },
- { icon .. " ", set_hl(hl) },
- { language .. " ", set_hl(config_table.name_hl) or set_hl(hl) },
+ { " " .. icon .. " ", set_hl(hl) },
+ { languageName .. " ", set_hl(config_table.name_hl) or set_hl(hl) },
},
sign_text = config_table.sign == true and icon or nil,
@@ -835,10 +1009,19 @@ renderer.render_code_blocks = function (buffer, content, config_table)
});
end
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_end - 1, content.col_start + 3, {
+ -- The text on the final line
+ -- We need to get the tail section to see if it contains ```
+ local block_end_line = vim.api.nvim_buf_get_lines(buffer, content.row_end - 1, content.row_end, false)[1];
+ local tail_section = vim.fn.strcharpart(block_end_line or "", content.col_start);
+
+ if tail_section:match("```$") then
+ tail_section = tail_section:gsub("```$", "");
+ end
+
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_end - 1, vim.fn.strchars(block_end_line or ""), {
virt_text_pos = config_table.position or "inline",
virt_text = {
- { string.rep(config_table.pad_char or " ", block_length + ((config_table.pad_amount or 1) * 2)), set_hl(config_table.hl) },
+ { string.rep(config_table.pad_char or " ", (block_length - vim.fn.strchars(tail_section)) + ((config_table.pad_amount or 1) * 2)), set_hl(config_table.hl) },
},
hl_mode = "combine",
@@ -859,7 +1042,7 @@ renderer.render_code_blocks = function (buffer, content, config_table)
}
})
- local position, reduce_cols = get_str_width(text)
+ local position, reduce_cols = get_str_width(text);
vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start + line, position, {
virt_text_pos = "inline",
@@ -879,16 +1062,16 @@ end
renderer.render_block_quotes = function (buffer, content, config_table)
local qt_config;
- if config_table.enable == false then
+ if not config_table or config_table.enable == false then
return;
end
if content.callout ~= nil then
for _, callout in ipairs(config_table.callouts) do
- if type(callout.match_string) == "string" and callout.match_string:upper() == content.callout:upper() then
+ if type(callout.match_string) == "string" and string.upper(callout.match_string --[[@as string]]) == content.callout:upper() then
qt_config = callout;
- elseif vim.islist(callout.aliases) then
- for _, alias in ipairs(callout.aliases) do
+ elseif vim.islist(callout.match_string) then
+ for _, alias in ipairs(callout.match_string --[[@as string[] ]]) do
if type(alias) == "string" and alias:upper() == content.callout.upper() then
qt_config = callout;
end
@@ -903,6 +1086,11 @@ renderer.render_block_quotes = function (buffer, content, config_table)
qt_config = config_table.default;
end
+ -- Config for a block quote is not available
+ if not qt_config then
+ return;
+ end
+
if qt_config.custom_title == true and content.title ~= "" then
vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_start, {
virt_text_pos = "inline",
@@ -971,7 +1159,7 @@ end
renderer.render_horizontal_rules = function (buffer, content, config_table)
local virt_text = {};
- if config_table.enable == false then
+ if not config_table or config_table.enable == false then
return;
end
@@ -1025,18 +1213,23 @@ end
renderer.render_links = function (buffer, content, config_table)
local lnk_conf;
- if config_table.enable == false then
+ if not config_table or config_table.enable == false then
return;
end
if content.link_type == "inline_link" then
- lnk_conf = config_table.inline_links;
+ lnk_conf = config_table.hyperlinks;
elseif content.link_type == "image" then
lnk_conf = config_table.images;
elseif content.link_type == "email_autolink" then
lnk_conf = config_table.emails;
end
+ -- Do not render links with no config
+ if not lnk_conf then
+ return;
+ end
+
vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.link_type == "email_autolink" and content.col_start or content.col_start + 1, {
virt_text_pos = "inline",
virt_text = {
@@ -1068,7 +1261,7 @@ end
---@param content any
---@param config_table markview.render_config.inline_codes
renderer.render_inline_codes = function (buffer, content, config_table)
- if config_table.enable == false then
+ if not config_table or config_table.enable == false then
return;
end
@@ -1083,7 +1276,7 @@ renderer.render_inline_codes = function (buffer, content, config_table)
vim.api.nvim_buf_add_highlight(buffer, renderer.namespace, set_hl(config_table.hl), content.row_start, content.col_start, content.col_end);
- vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_end - 1, {
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_end, {
virt_text_pos = "inline",
virt_text = {
{ config_table.padding_right or "", set_hl(config_table.padding_right_hl) or set_hl(config_table.hl) },
@@ -1097,7 +1290,7 @@ end
---@param content any
---@param config_table markview.render_config.list_items
renderer.render_lists = function (buffer, content, config_table)
- if config_table.enable == false then
+ if not config_table or config_table.enable == false then
return;
end
@@ -1113,6 +1306,11 @@ renderer.render_lists = function (buffer, content, config_table)
ls_conf = config_table.marker_dot or {};
end
+ -- Do not render list types with no configuraton
+ if not ls_conf then
+ return;
+ end
+
local use_text = ls_conf.text or content.marker_symbol;
if ls_conf.add_padding == true then
@@ -1162,7 +1360,7 @@ end
---@param content any
---@param config_table markview.render_config.checkboxes
renderer.render_checkboxes = function (buffer, content, config_table)
- if config_table.enable == false then
+ if not config_table or config_table.enable == false then
return;
end
@@ -1176,7 +1374,7 @@ renderer.render_checkboxes = function (buffer, content, config_table)
chk_config = config_table.pending;
end
- if type(chk_config.text) ~= "string" then
+ if not chk_config or type(chk_config.text) ~= "string" then
return;
end
@@ -1198,14 +1396,14 @@ end
---@param content any
---@param user_config markview.config
renderer.render_tables = function (buffer, content, user_config)
- if user_config.tables == nil or user_config.tables.enable == false then
+ if not user_config.tables or user_config.tables.enable == false then
return;
end
for row_number, _ in ipairs(content.rows) do
if content.row_type[row_number] == "header" then
table_header(buffer, content, user_config);
- elseif content.row_type[row_number] == "seperator" then
+ elseif content.row_type[row_number] == "separator" then
table_seperator(buffer, content, user_config, row_number)
elseif content.row_type[row_number] == "content" and row_number == #content.rows then
table_footer(buffer, content, user_config)
@@ -1215,82 +1413,66 @@ renderer.render_tables = function (buffer, content, user_config)
end
end
+renderer.render_html_inline = function (buffer, content, user_config)
+ if not user_config or user_config.enable == false then
+ return;
+ end
-
-
---- CursorMove listener
-renderer.autocmd = nil;
-
-renderer.create_autocmd = function (config_table)
- if renderer.autocmd then
+ if not user_config.tags or user_config.tags.enable == false then
return;
end
- local events = { "CursorMovedI" };
+ local html_conf = user_config.tags.default or {};
- -- if config_table.modes and vim.list_contains(config_table.modes, "i") then
- -- table.insert(events, "CursorMovedI");
- -- end
+ if user_config.tags.configs[string.lower(content.tag)] then
+ html_conf = user_config.tags.configs[string.lower(content.tag)];
+ end
- renderer.autocmd = vim.api.nvim_create_autocmd(events, {
- pattern = config_table.filetypes or "*.md", -- Currently only for markdown
- callback = function (event)
- local buffer = event.buf;
- local mode = vim.api.nvim_get_mode().mode;
+ if html_conf.conceal ~= false then
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.start_tag_col_start, {
+ end_col = content.start_tag_col_end,
+ conceal = ""
+ });
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.end_tag_col_start, {
+ end_col = content.end_tag_col_end,
+ conceal = ""
+ });
+ end
- if not vim.list_contains(config_table.modes or {}, mode) then
- return;
- end
+ if html_conf.hl then
+ vim.api.nvim_buf_add_highlight(buffer, renderer.namespace, html_conf.hl, content.row_start, content.start_tag_col_end, content.end_tag_col_start);
+ end
+end
- renderer.render_deleted_items(buffer, config_table);
- renderer.removed_elements[buffer] = {};
+renderer.render_html_entities = function (buffer, content, user_config)
+ if not user_config or user_config.enable == false then
+ return;
+ end
- if not vim.list_contains(config_table.special_modes or { "i" }, mode) then
- return;
- end
+ if not user_config.entites or user_config.entites.enable == false then
+ return;
+ end
- -- This is for testing purposes
- local cursor = vim.api.nvim_win_get_cursor(0);
- local comps = {};
+ local filtered_entity = content.text:gsub("[&;]", "");
+ local entity = entites.get(filtered_entity);
- for _, component in ipairs(_G.__markview_views[buffer] or {}) do
- if (cursor[1] - 1) >= component.row_start and cursor[1] - 1 <= component.row_end then
- table.insert(comps, component);
- table.insert(renderer.removed_elements[buffer], component);
- end
- end
+ if not entity then
+ return;
+ end
- renderer.destroy(buffer)
- end
- })
-end
+ vim.api.nvim_buf_set_extmark(buffer, renderer.namespace, content.row_start, content.col_start, {
+ virt_text_pos = "inline",
+ virt_text = {
+ { entity, set_hl(user_config.entites.hl) }
+ },
-renderer.destroy = function (buffer)
- -- if not renderer.removed_elements or not renderer.removed_elements[buffer] or vim.tbl_isempty(renderer.removed_elements[buffer]) then
- -- return;
- -- end
- --
- -- local max_range = {};
- --
- -- for _, content in ipairs(renderer.removed_elements[buffer]) do
- -- if not max_range[1] or content.row_start < max_range[1] then
- -- max_range[1] = content.row_start;
- -- end
- --
- -- if not max_range[2] or content.row_end > max_range[2] then
- -- max_range[2] = content.row_end;
- -- end
- -- end
- --
- -- vim.api.nvim_buf_clear_namespace(buffer, renderer.namespace, max_range[1], max_range[2] + 1);
+ end_col = content.col_end,
+ conceal = ""
+ });
end
-renderer.render_deleted_items = function (buffer, config_table)
- if not renderer.removed_elements[buffer] then
- return;
- end
-
- for _, content in ipairs(renderer.removed_elements[buffer]) do
+renderer.render_in_range = function (buffer, partial_contents, config_table)
+ for _, content in ipairs(partial_contents) do
local type = content.type;
local fold_closed = vim.fn.foldclosed(content.row_start + 1);
@@ -1298,29 +1480,32 @@ renderer.render_deleted_items = function (buffer, config_table)
goto extmark_skipped;
end
-
if type == "heading_s" then
- renderer.render_headings_s(buffer, content, config_table.headings);
+ pcall(renderer.render_headings_s, buffer, content, config_table.headings);
elseif type == "heading" then
- renderer.render_headings(buffer, content, config_table.headings)
+ pcall(renderer.render_headings, buffer, content, config_table.headings)
elseif type == "code_block" then
- renderer.render_code_blocks(buffer, content, config_table.code_blocks)
+ pcall(renderer.render_code_blocks, buffer, content, config_table.code_blocks)
elseif type == "block_quote" then
- renderer.render_block_quotes(buffer, content, config_table.block_quotes);
+ pcall(renderer.render_block_quotes, buffer, content, config_table.block_quotes);
elseif type == "horizontal_rule" then
- renderer.render_horizontal_rules(buffer, content, config_table.horizontal_rules);
+ pcall(renderer.render_horizontal_rules, buffer, content, config_table.horizontal_rules);
elseif type == "link" then
- renderer.render_links(buffer, content, config_table.links);
+ pcall(renderer.render_links, buffer, content, config_table.links);
elseif type == "image" then
- renderer.render_links(buffer, content, config_table.images);
+ pcall(renderer.render_links, buffer, content, config_table.images);
elseif type == "inline_code" then
- renderer.render_inline_codes(buffer, content, config_table.inline_codes)
+ pcall(renderer.render_inline_codes, buffer, content, config_table.inline_codes)
elseif type == "list_item" then
- renderer.render_lists(buffer, content, config_table.list_items)
+ pcall(renderer.render_lists, buffer, content, config_table.list_items)
elseif type == "checkbox" then
- renderer.render_checkboxes(buffer, content, config_table.checkboxes)
+ pcall(renderer.render_checkboxes, buffer, content, config_table.checkboxes)
+ elseif type == "html_inline" then
+ pcall(renderer.render_html_inline, buffer, content, config_table.html);
+ elseif type == "html_entity" then
+ pcall(renderer.render_html_entities, buffer, content, config_table.html);
elseif type == "table" then
- renderer.render_tables(buffer, content, config_table)
+ pcall(renderer.render_tables, buffer, content, config_table)
end
::extmark_skipped::
@@ -1336,6 +1521,11 @@ renderer.render = function (buffer, parsed_content, config_table, conceal_start,
_G.__markview_views[buffer] = parsed_content;
end
+ -- Prevents errors caused by buffer ranges being nil
+ if _G.__markview_render_ranges and _G.__markview_render_ranges[buffer] then
+ _G.__markview_render_ranges[buffer] = {};
+ end
+
for _, content in ipairs(_G.__markview_views[buffer]) do
local type = content.type;
local fold_closed = vim.fn.foldclosed(content.row_start + 1);
@@ -1344,113 +1534,87 @@ renderer.render = function (buffer, parsed_content, config_table, conceal_start,
goto extmark_skipped;
end
- -- if conceal_start and conceal_stop and content.row_start >= conceal_start and content.row_end <= conceal_stop then
- -- goto extmark_skipped;
- -- end
+ -- Unlike `conceal_start`, `conceal_stop` is 1-indexed
+ -- Do not render things inside the un-conceal range
+ if conceal_start and conceal_stop and content.row_start >= conceal_start and content.row_end <= (conceal_stop - 1) then
+ goto extmark_skipped;
+ end
if type == "heading_s" then
- renderer.render_headings_s(buffer, content, config_table.headings);
+ pcall(renderer.render_headings_s, buffer, content, config_table.headings);
elseif type == "heading" then
- renderer.render_headings(buffer, content, config_table.headings)
+ pcall(renderer.render_headings, buffer, content, config_table.headings)
elseif type == "code_block" then
- renderer.render_code_blocks(buffer, content, config_table.code_blocks)
+ pcall(renderer.render_code_blocks, buffer, content, config_table.code_blocks)
elseif type == "block_quote" then
- renderer.render_block_quotes(buffer, content, config_table.block_quotes);
+ pcall(renderer.render_block_quotes, buffer, content, config_table.block_quotes);
elseif type == "horizontal_rule" then
- renderer.render_horizontal_rules(buffer, content, config_table.horizontal_rules);
+ pcall(renderer.render_horizontal_rules, buffer, content, config_table.horizontal_rules);
elseif type == "link" then
- renderer.render_links(buffer, content, config_table.links);
+ pcall(renderer.render_links, buffer, content, config_table.links);
elseif type == "image" then
- renderer.render_links(buffer, content, config_table.images);
+ pcall(renderer.render_links, buffer, content, config_table.images);
elseif type == "inline_code" then
- renderer.render_inline_codes(buffer, content, config_table.inline_codes)
+ pcall(renderer.render_inline_codes, buffer, content, config_table.inline_codes)
elseif type == "list_item" then
- renderer.render_lists(buffer, content, config_table.list_items)
+ pcall(renderer.render_lists, buffer, content, config_table.list_items)
elseif type == "checkbox" then
- renderer.render_checkboxes(buffer, content, config_table.checkboxes)
+ pcall(renderer.render_checkboxes, buffer, content, config_table.checkboxes)
+ elseif type == "html_inline" then
+ pcall(renderer.render_html_inline, buffer, content, config_table.html);
+ elseif type == "html_entity" then
+ pcall(renderer.render_html_entities, buffer, content, config_table.html);
elseif type == "table" then
- renderer.render_tables(buffer, content, config_table)
+ pcall(renderer.render_tables, buffer, content, config_table);
end
::extmark_skipped::
end
end
-renderer.clear = function (buffer)
- vim.api.nvim_buf_clear_namespace(buffer, renderer.namespace, 0, -1)
+renderer.clear = function (buffer, from, to)
+ vim.api.nvim_buf_clear_namespace(buffer, renderer.namespace, from or 0, to or -1)
end
-renderer.clear_under_cursor = function (buffer, cursor)
- if not _G.__markview_views[buffer] then
- return;
- elseif not renderer.removed_elements then
- renderer.removed_elements = {};
+renderer.update_range = function (buffer, new_range)
+ if not _G.__markview_render_ranges then
+ _G.__markview_render_ranges = {};
end
- if not renderer.removed_elements[buffer] then
- renderer.removed_elements[buffer] = {};
+ if not _G.__markview_render_ranges[buffer] then
+ _G.__markview_render_ranges[buffer] = {};
end
- renderer.clear_elements(buffer, cursor);
+ if new_range and not vim.deep_equal(_G.__markview_render_ranges[buffer], new_range) then
+ _G.__markview_render_ranges[buffer] = new_range;
+ end
end
-renderer.render_partial = function (buffer, partial_contents, config_table, conceal_start, conceal_stop)
- -- if not renderer.removed_elements[buffer] then
- -- return
- -- end
-
- for _, content in ipairs(partial_contents) do
- local type = content.type;
- local fold_closed = vim.fn.foldclosed(content.row_start + 1);
-
- if fold_closed ~= -1 then
- goto extmark_skipped;
- end
+renderer.clear_content_range = function (buffer, parsed_content)
+ local max_range = { nil, nil };
- if content.row_start >= conceal_start and content.row_end <= conceal_stop then
- goto extmark_skipped;
+ for _, content in ipairs(parsed_content) do
+ if not max_range[1] or (content.row_start) < max_range[1] then
+ max_range[1] = content.row_start;
end
-
- if type == "heading_s" then
- renderer.render_headings_s(buffer, content, config_table.headings);
- elseif type == "heading" then
- renderer.render_headings(buffer, content, config_table.headings)
- elseif type == "code_block" then
- renderer.render_code_blocks(buffer, content, config_table.code_blocks)
- elseif type == "block_quote" then
- renderer.render_block_quotes(buffer, content, config_table.block_quotes);
- elseif type == "horizontal_rule" then
- renderer.render_horizontal_rules(buffer, content, config_table.horizontal_rules);
- elseif type == "link" then
- renderer.render_links(buffer, content, config_table.links);
- elseif type == "image" then
- renderer.render_links(buffer, content, config_table.images);
- elseif type == "inline_code" then
- renderer.render_inline_codes(buffer, content, config_table.inline_codes)
- elseif type == "list_item" then
- renderer.render_lists(buffer, content, config_table.list_items)
- elseif type == "checkbox" then
- renderer.render_checkboxes(buffer, content, config_table.checkboxes)
- elseif type == "table" then
- renderer.render_tables(buffer, content, config_table)
+ if not max_range[2] or (content.row_end) > max_range[2] then
+ max_range[2] = content.row_end;
end
-
- ::extmark_skipped::
end
-end
-renderer.update = function (buffer, parsed_content)
- if not _G.__markview_views then
- _G.__markview_views = {};
+ if not max_range[1] or not max_range[2] then
+ return;
end
- if parsed_content ~= nil then
- _G.__markview_views[buffer] = parsed_content;
+ if max_range[1] == max_range[2] then
+ max_range[2] = max_range[2] + 1;
end
+
+ vim.api.nvim_buf_clear_namespace(buffer, renderer.namespace, max_range[1], max_range[2]);
end
-renderer.clear_partial_range = function (buffer, parsed_content)
+renderer.get_content_range = function (parsed_content)
local max_range = { nil, nil };
for _, content in ipairs(parsed_content) do
@@ -1471,12 +1635,7 @@ renderer.clear_partial_range = function (buffer, parsed_content)
max_range[2] = max_range[2] + 1;
end
- if not _G.__markview_render_ranges then
- _G.__markview_render_ranges = {};
- end
-
- _G.__markview_render_ranges[buffer] = max_range;
- vim.api.nvim_buf_clear_namespace(buffer, renderer.namespace, max_range[1], max_range[2]);
+ return max_range;
end
return renderer;
diff --git a/lua/markview/utils.lua b/lua/markview/utils.lua
index 888d6a3..92efda2 100644
--- a/lua/markview/utils.lua
+++ b/lua/markview/utils.lua
@@ -1,5 +1,9 @@
local utils = {};
+utils.clamp = function (val, min, max)
+ return math.min(math.max(val, min), max);
+end
+
utils.find_attached_wins = function (buf)
local attached_wins = {};
@@ -12,11 +16,11 @@ utils.find_attached_wins = function (buf)
return attached_wins;
end
-utils.get_cursor_range = function (buffer, window, config_table)
+utils.get_cursor_range = function (buffer, window)
local cursor = vim.api.nvim_win_get_cursor(window or 0);
local lines = vim.api.nvim_buf_line_count(buffer);
- return math.max(0, (cursor[1] - 1) - (config_table.draw_range or 1)), math.min(lines, (cursor[1] - 1) + (config_table.draw_range or 1));
+ return math.max(0, cursor[1] - 1), math.min(lines, cursor[1]);
end
return utils;
diff --git a/markview.nvim.wiki b/markview.nvim.wiki
new file mode 160000
index 0000000..873da3f
--- /dev/null
+++ b/markview.nvim.wiki
@@ -0,0 +1 @@
+Subproject commit 873da3fa850e608a7c51023bbd54bae453757b66
diff --git a/showcases/demo.md b/showcases/demo.md
new file mode 100644
index 0000000..6881174
--- /dev/null
+++ b/showcases/demo.md
@@ -0,0 +1,45 @@
+# Makrview.nvim
+
+An experimental markdown previewer for Neovim.
+
+```lua
+vim.print(require("markview").state);
+```
+
+## Tasks
+
+- [X] Stability improvements
+- [ ] Rocks.nvim workflow
+- [-] Wiki updates
+
+## Links
+
+[Markview.nvim](https://www.github.com/markview.nvim)
+![Showcase](../img/showcase.jpg)
+
+
+## Notifications
+
+>[!Important]
+> Old presets are about to be removed.
+
+>[!Tip]
+> Don't forget to check the wiki!
+
+>[!Warning]
+> Only for Neovim `0.10.0` and higher.
+
+## Github Insights
+
+| Entry name | Entry value |
+|:------------------------|:-----------------------|
+| Git clones | 1008 |
+| Visitors | 3801 |
+| Stars | 777 |
+| Lines added | 8426 |
+| Lines deleted | 3158 |
+
+
+
diff --git a/showcases/html.md b/showcases/html.md
new file mode 100644
index 0000000..b29962f
--- /dev/null
+++ b/showcases/html.md
@@ -0,0 +1,56 @@
+# Makrview.nvim
+
+An experimental markdown previewer for Neovim.
+
+## Basic html tag support
+
+Markview.nvim supports some simple `html`.
+
+For example,
+
+- Bold: Example text
+- Strong: Example text
+- Underline: Example text
+- Italic: Example text
+- Emphasize: Example text
+- Marked: Example text
+
+These tags can also be used inside of your Normal text.
+
+## Html entity support
+
+Markview.nvim has basic support of `html entites`.
+
+ ← ↓ ↑ →
+
+ ∠ ≡ ∫ ≥ ≤ > < ∞ ∈ ∅
+ ½ ¼ ¾
+
+And a lot more symbols are also supported.
+
+## Supported in tables
+
+| Using tags in tables | Using entites in tables |
+|:------------------------------:|---------------------------|
+| Single tag usage | Single entity(←) |
+| Multi tag usage | ∠ ¾ |
+| =|= |
+| You can also use both together: Underline & 〉 |
+
+>[!Note]
+> Html support is exclusive to tables! Other block elements
+> will render them as raw text.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/showcases/hybrid_mode.md b/showcases/hybrid_mode.md
new file mode 100644
index 0000000..162b5fa
--- /dev/null
+++ b/showcases/hybrid_mode.md
@@ -0,0 +1,37 @@
+# Markview.nvim
+
+An experimental markdown previewer for Neovim.
+
+Hybrid mode:
+A way to preview & edit at the same time
+---
+
+It is now possible to see previews as you type.
+
+It works for all kinds of elements such as `inline codes`,
+*italic*, **bold** etc.
+
+It also works for block elements.
+
+```lua
+vim.print("Hello world");
+```
+
+>[!Tip]
+> It can also work on nested elements.
+>
+> ```vim
+> set scrolloff=0
+> ```
+
+It even works on list items,
+- Item 1
+- Item 2
+ - Nested 1
+ - Nested 2
+
+---
+
+
diff --git a/test.md b/test.md
deleted file mode 100644
index e201323..0000000
--- a/test.md
+++ /dev/null
@@ -1,24 +0,0 @@
-- Hello
-- My name is
-- MD
- - Moinul
- - Hossain
- - Shawon
-- I like to do
-- programming
-
-
-
->[!IMPORTANT]
-> dudjdjd
-
-> heidjejd
-> jdidjdjdjd
-
-
-
-
-
-
-# Heklo
-
diff --git a/wiki b/wiki
deleted file mode 160000
index 9d04479..0000000
--- a/wiki
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 9d04479666463d12a2a406e1a2ca8e9cc5c6ef28