{"id":13525062,"url":"https://github.com/sontungexpt/better-diagnostic-virtual-text","last_synced_at":"2025-04-23T01:22:33.309Z","repository":{"id":247078706,"uuid":"824962094","full_name":"sontungexpt/better-diagnostic-virtual-text","owner":"sontungexpt","description":"Enhances the display of virtual text for diagnostics in Neovim. This function aims to provide a more user-friendly and informative presentation of diagnostic messages directly within the editor.","archived":false,"fork":false,"pushed_at":"2024-07-27T16:25:08.000Z","size":102,"stargazers_count":78,"open_issues_count":2,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-29T20:51:06.531Z","etag":null,"topics":["diagnostic","lua","neovim","nvim","nvim-lua","nvim-plugin"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sontungexpt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-06T12:09:27.000Z","updated_at":"2025-03-11T08:11:37.000Z","dependencies_parsed_at":"2024-10-28T04:07:19.318Z","dependency_job_id":null,"html_url":"https://github.com/sontungexpt/better-diagnostic-virtual-text","commit_stats":null,"previous_names":["sontungexpt/better-diagnostic-virtual-text"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sontungexpt%2Fbetter-diagnostic-virtual-text","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sontungexpt%2Fbetter-diagnostic-virtual-text/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sontungexpt%2Fbetter-diagnostic-virtual-text/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sontungexpt%2Fbetter-diagnostic-virtual-text/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sontungexpt","download_url":"https://codeload.github.com/sontungexpt/better-diagnostic-virtual-text/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250349981,"owners_count":21416044,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["diagnostic","lua","neovim","nvim","nvim-lua","nvim-plugin"],"created_at":"2024-08-01T06:01:15.659Z","updated_at":"2025-04-23T01:22:33.280Z","avatar_url":"https://github.com/sontungexpt.png","language":"Lua","funding_links":[],"categories":["LSP"],"sub_categories":["(requires Neovim 0.5)","Diagnostics"],"readme":"# Better Diagnostic Virtual Text\n\nA Neovim plugin for enhanced diagnostic virtual text display, aiming to provide better performance and customization options.\n\n**NOTE**: This code is currently in the testing phase and may contain bugs. If you encounter any issues, please let me know.\nI can't found it alone, so please help me to improve it.\n\n## Features\n\n- **Ease of Use**: Effortless setup and configuration.\n- **Beautiful UI**: Customizable colors, icons, and more for an aesthetically pleasing interface.\n- **Auto-fix Capability**: Automatically adjusts to fit the current window size for seamless display.\n- **Toggleable**: Easily enable or disable using `vim.diagnostic.enable/disable` commands.\n- **Performance**: Optimized for speed and efficiency, updating virtual text only when necessary.\n\n## Preview\n\n- opts.inline = false. Show all diagnostics\n\nhttps://github.com/sontungexpt/better-diagnostic-virtual-text/assets/92097639/67212285-6534-4758-a943-5938500e0077\n\n- opts.inline = true. Show only current line diagnostic\n\nhttps://github.com/sontungexpt/better-diagnostic-virtual-text/assets/92097639/ef3d49fb-1a47-46c3-81ba-d23df70eced9\n\n- opts.ui.above = true. Show the diagnostic above the line\n\nhttps://github.com/sontungexpt/better-diagnostic-virtual-text/assets/92097639/c2c30f61-6e9b-4986-a27f-21c916f7e1bd\n\n- Test with tokyonight theme\n\nhttps://github.com/sontungexpt/better-diagnostic-virtual-text/assets/92097639/4e0f6306-0fc4-4fb4-b46f-107b8c40e46c\n\n## Installation\n\nYou need to set vim.diagnostic.config({ virtual_text = false }), to not have all diagnostics in the buffer displayed conflict.\nMay be in the future we will integrate it with native vim.diagnostic\n\nAdd the following to your `init.lua` or `init.vim`:\n\n```lua\n-- lazy.nvim\n{\n    'sontungexpt/better-diagnostic-virtual-text',\n    \"LspAttach\"\n    config = function(_)\n        require('better-diagnostic-virtual-text').setup(opts)\n    end\n}\n\n-- or better ways configure in on_attach of lsp client\n-- if use this way don't need to call setup function\n{\n    'sontungexpt/better-diagnostic-virtual-text',\n    lazy = true,\n}\nM.on_attach = function(client, bufnr)\n    -- nil can replace with the options of each buffer\n\trequire(\"better-diagnostic-virtual-text.api\").setup_buf(bufnr, {})\n\n    --- ... other config for lsp client\nend\n```\n\n## Configuration\n\n```lua\n-- Can be applied to each buffer separately\n\nlocal default_options = {\n    ui = {\n        wrap_line_after = false, -- wrap the line after this length to avoid the virtual text is too long\n        left_kept_space = 3, --- the number of spaces kept on the left side of the virtual text, make sure it enough to custom for each line\n        right_kept_space = 3, --- the number of spaces kept on the right side of the virtual text, make sure it enough to custom for each line\n        arrow = \"  \",\n        up_arrow = \"  \",\n        down_arrow = \"  \",\n        above = false, -- the virtual text will be displayed above the line\n    },\n    priority = 2003, -- the priority of virtual text\n    inline = true,\n}\n```\n\n### Customize ui\n\nUI will has 4 parts: arrow, left_kept_space, message, right_kept_space orders:\n\n| arrow | left_kept_space | message | right_kept_space |\n\n- arrow: This part is the arrow symbol that indicates the severity of the diagnostic message.\n- left_kept_space: The space to keep on the left side of the virtual text. Please make sure it enough to custom for each line.\n  Default this part is the tree in virtual text.\n- message: The message at the current line.\n- right_kept_space: The space to keep on the right side of the virtual text. Please make sure it enough to custom for each line.\n\nOverride this function before setup the plugin.\n\n```lua\n--- Format line chunks for virtual text display.\n---\n--- This function formats the line chunks for virtual text display, considering various options such as severity,\n--- underline symbol, text offsets, and parts to be removed.\n---\n--- @param ui_opts table - The table of UI options. Should contain:\n---     - arrow: The symbol used as the left arrow.\n---     - up_arrow: The symbol used as the up arrow.\n---     - down_arrow: The symbol used as the down arrow.\n---     - left_kept_space: The space to keep on the left side.\n---     - right_kept_space: The space to keep on the right side.\n---     - wrap_line_after: The maximum line length to wrap after.\n--- @param line_idx number - The index of the current line (1-based). It start from the cursor line to above or below depend on the above option.\n--- @param line_msg string - The message to display on the line.\n--- @param severity number - The severity level of the diagnostic (1 = Error, 2 = Warn, 3 = Info, 4 = Hint).\n--- @param max_line_length number - The maximum length of the line.\n--- @param lasted_line boolean - Whether this is the last line of the diagnostic message. Please check line_idx == 1 to know the first line before checking lasted_line because the first line can be the lasted line if the message has only one line.\n--- @param virt_text_offset number - The offset for virtual text positioning.\n--- @param should_display_below boolean - Whether to display the virtual text below the line. If above is true, this option will be whether the virtual text should be above\n--- @param above_instead boolean - Display above or below\n--- @param removed_parts table - A table indicating which parts should be deleted and make room for message (e.g., arrow, left_kept_space, right_kept_space).\n--- @param diagnostic table - The diagnostic to display. see `:help vim.Diagnostic.` for more information.\n--- @return table - A list of formatted chunks for virtual text display.\n--- @see vim.api.nvim_buf_set_extmark\nfunction M.format_line_chunks(\n\tui_opts,\n\tline_idx,\n\tline_msg,\n\tseverity,\n\tmax_line_length,\n\tlasted_line,\n\tvirt_text_offset,\n\tshould_display_below,\n\tabove_instead,\n\tremoved_parts,\n\tdiagnostic\n)\n\tlocal chunks = {}\n\tlocal first_line = line_idx == 1\n\tlocal severity_suffix = SEVERITY_SUFFIXS[severity]\n\n\tlocal function hls(extend_hl_groups)\n\t\tlocal default_groups = {\n\t\t\t\"DiagnosticVirtualText\" .. severity_suffix,\n\t\t\t\"BetterDiagnosticVirtualText\" .. severity_suffix,\n\t\t}\n\t\tif extend_hl_groups then\n\t\t\tfor i, hl in ipairs(extend_hl_groups) do\n\t\t\t\tdefault_groups[2 + i] = hl\n\t\t\tend\n\t\tend\n\t\treturn default_groups\n\tend\n\n\tlocal message_highlight = hls()\n\n\tif should_display_below then\n\t\tlocal arrow_symbol = (above_instead and ui_opts.down_arrow or ui_opts.up_arrow):match(\"^%s*(.*)\")\n\t\tlocal space_offset = space(virt_text_offset)\n\t\tif first_line then\n\t\t\tif not removed_parts.arrow then\n\t\t\t\ttbl_insert(chunks, {\n\t\t\t\t\tspace_offset .. arrow_symbol,\n\t\t\t\t\thls({ \"BetterDiagnosticVirtualTextArrow\", \"BetterDiagnosticVirtualTextArrow\" .. severity_suffix }),\n\t\t\t\t})\n\t\t\tend\n\t\telse\n\t\t\ttbl_insert(chunks, {\n\t\t\t\tspace_offset .. space(strdisplaywidth(arrow_symbol)),\n\t\t\t\tmessage_highlight,\n\t\t\t})\n\t\tend\n\telse\n\t\tlocal arrow_symbol = ui_opts.arrow\n\t\tif first_line then\n\t\t\tif not removed_parts.arrow then\n\t\t\t\ttbl_insert(chunks, {\n\t\t\t\t\tarrow_symbol,\n\t\t\t\t\thls({ \"BetterDiagnosticVirtualTextArrow\", \"BetterDiagnosticVirtualTextArrow\" .. severity_suffix }),\n\t\t\t\t})\n\t\t\tend\n\t\telse\n\t\t\ttbl_insert(chunks, {\n\t\t\t\tspace(virt_text_offset + strdisplaywidth(arrow_symbol)),\n\t\t\t\tmessage_highlight,\n\t\t\t})\n\t\tend\n\tend\n\n\tif not removed_parts.left_kept_space then\n\t\tlocal tree_symbol = \"   \"\n\t\tif first_line then\n\t\t\tif not lasted_line then\n\t\t\t\ttree_symbol = above_instead and \" └ \" or \" ┌ \"\n\t\t\tend\n\t\telseif lasted_line then\n\t\t\ttree_symbol = above_instead and \" ┌ \" or \" └ \"\n\t\telse\n\t\t\ttree_symbol = \" │ \"\n\t\tend\n\t\ttbl_insert(chunks, {\n\t\t\ttree_symbol,\n\t\t\thls({ \"BetterDiagnosticVirtualTextTree\", \"BetterDiagnosticVirtualTextTree\" .. severity_suffix }),\n\t\t})\n\tend\n\n\ttbl_insert(chunks, {\n\t\tline_msg,\n\t\tmessage_highlight,\n\t})\n\n\tif not removed_parts.right_kept_space then\n\t\tlocal last_space = space(max_line_length - strdisplaywidth(line_msg) + ui_opts.right_kept_space)\n\t\ttbl_insert(chunks, { last_space, message_highlight })\n\tend\n\n\treturn chunks\nend\n\n```\n\n## Toggle\n\nYou can enable and disable the plugin using the following commands:\n\n```lua\n    vim.diagnostic.enable(true, { bufnr = vim.api.nvim_get_current_buf() }) -- Enable the plugin for the current buffer.\n    vim.diagnostic.enable(false, { bufnr = vim.api.nvim_get_current_buf() }) -- Disable the plugin for the current buffer.\n```\n\n## Highlight Names\n\n### Default\n\nThe default highlight names for each severity level are:\n\n- `DiagnosticVirtualTextError`\n- `DiagnosticVirtualTextWarn`\n- `DiagnosticVirtualTextInfo`\n- `DiagnosticVirtualTextHint`\n\n### Custom Overrides\n\nYou can override the default highlight names with:\n\n- `BetterDiagnosticVirtualTextError`\n- `BetterDiagnosticVirtualTextWarn`\n- `BetterDiagnosticVirtualTextInfo`\n- `BetterDiagnosticVirtualTextHint`\n\n### Arrow Highlights\n\nFor the arrow highlights, use:\n\n- `BetterDiagnosticVirtualTextArrow` for all severity levels.\n- `BetterDiagnosticVirtualTextArrowError`\n- `BetterDiagnosticVirtualTextArrowWarn`\n- `BetterDiagnosticVirtualTextArrowInfo`\n- `BetterDiagnosticVirtualTextArrowHint`\n\n### Tree Highlights\n\nFor the tree highlights, use:\n\n- `BetterDiagnosticVirtualTextTree` for all severity levels.\n- `BetterDiagnosticVirtualTextTreeError`\n- `BetterDiagnosticVirtualTextTreeWarn`\n- `BetterDiagnosticVirtualTextTreeInfo`\n- `BetterDiagnosticVirtualTextTreeHint`\n\n## Public API Functions\n\n**Replace `M` with the `require(\"better-diagnostic-virtual-text.api\")`.**\n\nNOTE : I was too lazy to write the complete API documentation, so I used ChatGPT to generate it. If there are any inaccuracies, please refer to the source for verification.\n\n### `M.inspect_cache()`\n\n- **Description**: Inspects the diagnostics cache for debugging purposes.\n- **Parameters**: None\n- **Returns**: None\n\n### `M.foreach_line(bufnr, callback)`\n\nIterates through each line of diagnostics in a specified buffer and invokes a callback function for each line. Ensures compatibility with Lua versions older than 5.2 by using the default `pairs` function directly, or with a custom `pairs` function that handles diagnostic metadata.\n\n### Example\n\n```lua\nlocal meta_pairs = function(t)\n  local metatable = getmetatable(t)\n  if metatable and metatable.__pairs then\n      return metatable.__pairs(t)\n  end\n  return pairs(t)\nend\n```\n\nusage:\n\n```lua\nrequire(\"better-diagnostic-virtual-text.api\").foreach_line(bufnr, function(line, diagnostics)\n  for _, diagnostic in meta_pairs(diagnostics) do\n    print(diagnostic.message)\n  end\nend)\n```\n\n### `M.clear_extmark_cache(bufnr)`\n\nClears the diagnostics extmarks for a buffer.\n\n- **Parameters:**\n  - `bufnr` (integer): The buffer number to clear the diagnostics for.\n\n### `M.update_diagnostics_cache(bufnr, line, diagnostic)`\n\n- **Description**: Updates the diagnostics cache for a specific buffer and line.\n- **Parameters**:\n  - `bufnr` (`integer`): The buffer number.\n  - `line` (`integer`): The line number.\n  - `diagnostic` (`table`): The new diagnostic to track or list of diagnostics to update.\n- **Returns**: None\n\n### `M.fetch_diagnostics(bufnr, line, recompute, comparator, finish_soon)`\n\n- **Description**: Retrieves diagnostics at a specific line in the specified buffer.\n- **Parameters**:\n  - `bufnr` (`integer`): The buffer number.\n  - `line` (`integer`): The line number.\n  - `recompute` (`boolean|nil`): Whether to recompute the diagnostics.\n  - `comparator` (`function|nil`): The comparator function to sort the diagnostics. If not provided, the diagnostics are not sorted.\n  - `finish_soon` (`boolean|function|nil`): If true, stops processing sort when a finish_soon(d) return true or finish_soon is boolean and severity 1 diagnostic is found. When stop immediately the return value is the list with only found diagnostic. This parameter only work if `comparator` is provided or `recompute`` = false\n    .\n- **Returns**:\n\n  - `table`: List of diagnostics sorted by severity.\n  - `integer`: Number of diagnostics.\n\n  **Note: if finish_soon == true, the list will only has one diagnostic fit the condition.**\n\n### `M.fetch_cursor_diagnostics(bufnr, current_line, current_col, recompute, comparator, finish_soon)`\n\n- **Description**: Retrieves diagnostics at the cursor position in the specified buffer.\n- **Parameters**:\n  - `bufnr` (`integer`): The buffer number.\n  - `current_line` (`integer`): Optional. The current line number. Defaults to cursor line.\n  - `current_col` (`integer`): Optional. The current column number. Defaults to cursor column.\n  - `recompute` (`boolean`): Optional. Whether to recompute diagnostics or use cached diagnostics. Defaults to false.\n  - `comparator` (`function|nil`): The comparator function to sort the diagnostics. If not provided, the diagnostics are not sorted.\n  - `finish_soon` (`boolean|function|nil`): If true, stops processing sort when a finish_soon(d) return true or finish_soon is boolean and severity 1 diagnostic is found under cursor. When stop immediately the return value is the list with only found diagnostic. This parameter only work if `comparator` is provided or `recompute`` = false\n- **Returns**:\n\n  - `table`: Diagnostics at the cursor position sorted by severity.\n  - `integer`: Number of diagnostics at the cursor position.\n  - `table`: Full list of diagnostics for the line sorted by severity.\n  - `integer`: Number of diagnostics in the line sorted by severity.\n\n  **Note: if finish_soon == true, the list will only has one diagnostic fit the condition.**\n\n### `M.fetch_top_cursor_diagnostic(bufnr, current_line, current_col, recompute)`\n\n- **Description**: Retrieves the diagnostic with the highest severity at the cursor position in the specified buffer.\n- **Parameters**:\n  - `bufnr` (`integer`): The buffer number.\n  - `current_line` (`integer`): Optional. The current line number. Defaults to cursor line.\n  - `current_col` (`integer`): Optional. The current column number. Defaults to cursor column.\n  - `recompute` (`boolean`): Optional. Whether to recompute diagnostics or use cached diagnostics. Defaults to false.\n- **Returns**:\n  - `table`: Diagnostic at the cursor position.\n  - `table`: Full list of diagnostics for the line.\n  - `integer`: Number of diagnostics in the list.\n\n### `M.format_line_chunks(ui_opts, line_idx, line_msg, severity, max_line_length, lasted_line, virt_text_offset, should_display_below, removed_parts, diagnostic)`\n\n- **Description**: Formats line chunks for virtual text display based on severity and UI options.\n- **Parameters**:\n  - `ui_opts` (`table`): Table of UI options.\n  - `line_idx` (`number`): Index of the current line (1-based).\n  - `line_msg` (`string`): Message to display on the line.\n  - `severity` (`number`): Severity level of the diagnostic.\n  - `max_line_length` (`number`): Maximum length of the line.\n  - `lasted_line` (`boolean`): Whether this is the last line of the diagnostic message.\n  - `virt_text_offset` (`number`): Offset for virtual text positioning.\n  - `should_display_below` (`boolean`): Whether to display virtual text below the line.\n  - `removed_parts` (`table`): Table indicating parts to delete to make room for message.\n  - `diagnostic` (`table`): The diagnostic to display.\n- **Returns**:\n  - `table`: List of formatted chunks for virtual text display.\n\n### `M.exists_any_diagnostics(bufnr, line)`\n\nChecks if diagnostics exist for a buffer at a line.\n\n- **Parameters:**\n\n  - `bufnr` (integer): The buffer number to check.\n  - `line` (integer): The line number to check.\n\n- **Returns:**\n  - `exists` (boolean): True if diagnostics exist, false otherwise.\n\n### `M.clean_diagnostics(bufnr, lines_or_diagnostic)`\n\nCleans diagnostics for a buffer.\n\n- **Parameters:**\n\n  - `bufnr` (integer): The buffer number.\n  - `lines_or_diagnostic` (number|table): Specifies the lines or diagnostic to clean.\n\n- **Returns:**\n  - `cleared` (boolean): True if any diagnostics were cleared, false otherwise.\n\n### `M.show_diagnostic(opts, bufnr, diagnostic, clean_opts)`\n\nDisplays a diagnostic for a buffer, optionally cleaning existing diagnostics before showing the new one.\n\n- **Parameters:**\n\n  - `opts` (table): Options for displaying the diagnostic.\n  - `bufnr` (integer): The buffer number.\n  - `diagnostic` (table): The diagnostic to show.\n  - `clean_opts` (number|table|nil): Options for cleaning diagnostics before showing the new one.\n  - `recompute_ui` (boolean|nil) Whether to recompute the diagnostics. Defaults to false.\n\n- **Returns:**\n  - `shown_line` (integer): The start line of the diagnostic where it was shown.\n  - `diagnostic` (table): The diagnostic that was shown.\n\n### `M.show_top_severity_diagnostic(opts, bufnr, current_line, recompute, clean_opts)`\n\nShows the highest severity diagnostic at the line for a buffer.\n\n- **Parameters:**\n\n  - `opts` (table): Options for displaying the diagnostic.\n  - `bufnr` (integer): The buffer number.\n  - `current_line` (integer): The current line number.\n  - `recompute` (boolean): Whether to recompute the diagnostics.\n  - `clean_opts` (number|table): Options for cleaning diagnostics before showing the new one.\n  - `recompute_ui` (boolean|nil) Whether to recompute the diagnostics. Defaults to false.\n\n- **Returns:**\n  - `line_number` (integer): The line number where the diagnostic was shown.\n  - `diagnostic` (table): The diagnostic that was shown.\n  - `diagnostics_list` (table): The list of diagnostics at the line.\n  - `size` (integer): The size of the diagnostics list.\n\n### `M.show_cursor_diagnostic(opts, bufnr, current_line, current_col, recompute, clean_opts)`\n\nShows the highest severity diagnostic at the cursor position in a buffer.\n\n- **Parameters:**\n\n  - `opts` (table): Options for displaying the diagnostic.\n  - `bufnr` (integer): The buffer number.\n  - `current_line` (integer): The current line number.\n  - `current_col` (integer): The current column number.\n  - `recompute` (boolean): Whether to recompute the diagnostics.\n  - `clean_opts` (number|table): Options for cleaning diagnostics before showing the new one.\n  - `recompute_ui` (boolean|nil) Whether to recompute the diagnostics. Defaults to false.\n\n- **Returns:**\n  - `line_number` (integer): The line number where the diagnostic was shown.\n  - `diagnostic` (table): The diagnostic that was shown.\n  - `diagnostics_list` (table): The list of diagnostics at the cursor position.\n  - `size` (integer): The size of the diagnostics list.\n\n### `M.get_shown_line_num(diagnostic)`\n\nReturns the line number where the diagnostic was shown.\n\n- **Parameters:**\n\n  - `diagnostic` (table): The diagnostic.\n\n- **Returns:**\n  - `line_shown` (integer): The line number where the diagnostic was shown.\n\n### `M.when_enabled(bufnr, callback)`\n\nInvokes a callback function when the plugin is enabled for a buffer.\n\n- **Parameters:**\n\n  - `bufnr` (integer): The buffer number.\n  - `callback` (function): The callback function to invoke.\n\n### `M.setup_buf(bufnr, opts)`\n\nSets up the buffer to handle diagnostic rendering and interaction.\n\n- **Parameters:**\n  - `bufnr` (integer): The buffer number.\n  - `opts` (table): Options for setting up the buffer.\n\n### `M.setup(opts)`\n\nSets up the module to handle diagnostic rendering and interaction globally.\n\n- **Parameters:**\n  - `opts` (table): Options for setting up the module.\n\n## License\n\nMIT [License](./LICENSE)\n\n## Contributors\n\n- [sontungexpt](https://github.com/sontungexpt)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsontungexpt%2Fbetter-diagnostic-virtual-text","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsontungexpt%2Fbetter-diagnostic-virtual-text","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsontungexpt%2Fbetter-diagnostic-virtual-text/lists"}