https://github.com/chrisgrieser/nvim-rulebook

All-around helper for dealing with errors and diagnostics: Prettify typescript errors, add inline-comments to ignore rules, and lookup rule documentation online.

https://github.com/chrisgrieser/nvim-rulebook

Science Score: 36.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
    Links to: researchgate.net
  • Committers with academic emails
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (10.7%) to scientific vocabulary

Keywords

diagnostic-tool formatter-plugin ignore-diagnostic linter-plugin neovim-plugin nvim-plugin pretty-errors ts-errors

Keywords from Contributors

archival projection interactive generic sequences pdf-summarization reference-management text-object alfred-workflow genomics
Last synced: 5 months ago · JSON representation

Repository

All-around helper for dealing with errors and diagnostics: Prettify typescript errors, add inline-comments to ignore rules, and lookup rule documentation online.

Basic Info
  • Host: GitHub
  • Owner: chrisgrieser
  • License: mit
  • Language: Lua
  • Default Branch: main
  • Homepage:
  • Size: 249 KB
Statistics
  • Stars: 99
  • Watchers: 2
  • Forks: 6
  • Open Issues: 0
  • Releases: 0
Topics
diagnostic-tool formatter-plugin ignore-diagnostic linter-plugin neovim-plugin nvim-plugin pretty-errors ts-errors
Created over 2 years ago · Last pushed 6 months ago
Metadata Files
Readme Funding License

README.md

nvim-rulebook 📖

badge

All-around helper for dealing with errors and diagnostics.

Features

  • Look up official rule documentation
  • Prettify unwieldy TypeScript error messages. Code blocks in the error message are formatted with prettier or biome if available.
  • Add inline-comments to ignore rules like // eslint disable-next-line some-rule. Supports previous line, same line, and enclosing lines.
  • Suppress formatting with inline comments of the respective formatter, such as // prettier-ignore.
  • Built-in support for more than 50 tools. Thus, this plugin requires zero configuration for most users.
Before error prettification After error prettification
showcase: before prettification showcase: after prettification

Table of contents

Supported sources

You easily add a custom source via the plugin configuration. Please consider making a PR to add support for a source if it is missing.

Rule data for built-in support of linters and formatters

Rule lookup

  • ansible-lint
  • basedpyright
  • biome
  • clang-tidy
  • eslint
  • ltex_plus
  • LTeX
  • Lua Diagnostics.
  • markdownlint
  • pylint
  • Pyrefly
  • Pyright
  • quick-lint-js
  • Ruff
  • selene
  • shellcheck
  • stylelint
  • stylelintplus
  • swiftlint
  • ts
  • tsserver
  • ty
  • typescript
  • yamllint

Add ignore comment

Suppress formatting

  • clang-format: c, cpp
  • prettier: css, html, javascript, javascriptreact, markdown, scss, svelte, typescript, typescriptreact, vue, yaml
  • ruff / black: python
  • stylua: lua <!-- auto-generated: end -->

Prettify errors

Currently only supports the TypeScript LSP (ts_ls).

Take a look at this file to see how to add prettifiers for other sources. PRs are welcome.

Installation

Requirements - nvim 0.10+ - Diagnostics provided by a source that supports Neovim's built-in diagnostics system. (nvim built-in LSP client, efm-langserver or nvim-lint are such sources.)

Recommended for error prettifying - treesitter parsers: TSInstall markdown markdown_inline - a markdown rendering plugin such as render-markdown or markview.nvim - prettier or biome available in PATH.

```lua -- lazy.nvim { "chrisgrieser/nvim-rulebook" },

-- packer use { "chrisgrieser/nvim-rulebook" } ```

Usage

You can use the commands via lua functions:

lua require("rulebook").ignoreRule() require("rulebook").prettifyError() require("rulebook").yankDiagnosticCode() require("rulebook").suppressFormatter() require("rulebook").prettifyError()

```lua -- snippets to create keymaps, for your convenience vim.keymap.set("n", "ri", function() require("rulebook").ignoreRule() end) vim.keymap.set("n", "rl", function() require("rulebook").lookupRule() end) vim.keymap.set("n", "ry", function() require("rulebook").yankDiagnosticCode() end) vim.keymap.set({ "n", "x" }, "rf", function() require("rulebook").suppressFormatter() end)

vim.api.nvimcreateautocmd("Filetype", { pattern = { "typescript", "javascript" }, group = vim.api.nvimcreateaugroup("rulebook.prettify-ts-error", { clear = true }), callback = function(ctx) vim.keymap.set( "n", "rp", function() require("rulebook").prettifyError() end, { buffer = ctx.buf } ) end, }) ```

Alternatively, you can use the :Rulebook ex-command:

vim :Rulebook ignoreRule :Rulebook lookupRule :Rulebook yankDiagnosticCode :Rulebook suppressFormatter :Rulebook prettifyError

Note that :Rulebook suppressFormatter only supports normal mode. To add formatter-ignore comments for a line range, you need to use the lua function require("rulebook").suppressFormatter() from visual mode.

Configuration

Base configuration

The .setup() call is optional. You only need to add a config when you want to add or customize sources.

When adding your own source, you must add the exact, case-sensitive source name (for example, clang-tidy, not clang).

```lua require("rulebook").setup = ({ -- if no diagnostic is found in the current line, search this many lines forward forwSearchLines = 10,

ignoreComments = {
    shellcheck = {
        comment = "# shellcheck disable=%s",
        location = "prevLine",
        multiRuleIgnore = true,
        multiRuleSeparator = ",",
    },
    -- ... (a full list of sources with builtin support can be found in the README)

    yourCustomSource = { -- exact, case-sensitive source-name
        ---@type string|fun(vim.Diagnostic): string if string, "%s" will be replaced with the rule id
        comment = "// disabling-comment %s",

        ---@type "prevLine"|"sameLine"|"encloseLine"|"inlineBeforeDiagnostic"|fun(vim.Diagnostic): string
        location = "sameLine",

        -- whether multiple rules can be ignored with one comment, defaults to `false`
        multiRuleIgnore = true,

        -- separator for multiple rule-ids, defaults to ", " (with space)
        multiRuleSeparator = ",",
    }

    -- if location is `encloseLine`, the comment needs to be a list of two strings
    anotherCustomSource = {
        location = "encloseLine",
        comment = { 
            "// disable-rule %s", 
            "// enable-rule %s",
        },
    }
},

ruleDocs = {
    selene = "https://kampfkarren.github.io/selene/lints/%s.html"
    -- ... (a full list of sources with builtin support can be found in the README)

    -- Search URL when no documentation definition is available for a
    -- diagnostic source. `%s` will be replaced with the diagnostic source and 
    -- the code/message.
    fallback = "https://www.google.com/search?q=%s",

    -- the key must be named exactly like `diagnostic.source` (case-sensitive!)
    -- * string: `%s` will be replaced with the rule id
    -- * function: will be called with the diagnostic object
    -- * `false`: disable rule docs, will use the fallback
    ---@type string|false|fun(diag: vim.Diagnostic): string?
    yourCustomSource = "https://my-docs/%s.hthml",
    anotherCustomSource = function(diag)
        -- ...
        return url
    end,
}

suppressFormatter = {
    lua = {
        -- used for normal mode
        ignoreBlock = "-- stylua: ignore",

        ---@type "prevLine"|"sameLine"|"encloseLine"|fun(): string
        location = "prevLine",

        -- used for visual mode
        ignoreRange = { "-- stylua: ignore start", "-- stylua: ignore end" },
    },
}

prettifyError = {
    ---@type fun(vim.Diagnostic): string[]
    typescript = function(diag)
  -- ...
    end,
}

}) ```

nvim-rulebook uses vim.ui.select, so the appearance of the rule selection can be customized by using a UI plugin like snacks.nvim.

Customize built-in sources

Built-in sources can be customized by overwriting them in the configuration:

lua -- example: use `disable-line` instead of the default `disable-next-line` for eslint require("rulebook").setup = { ignoreComments = { eslint = { comment = "// eslint-disable-line %s", location = "sameLine", }, }, }

FAQ

How to configure diagnostic providers

This plugin requires that the diagnostic providers (the LSP or a linter integration tool like nvim-lint or efm-langserver) provide the source and code for the diagnostic. - Make sure that the source is named the same in the diagnostic source and in the nvim-rulebook config, including casing. - For nvim-lint, most linters should already be configured out of the box. - For efm-langserver, you have to set lintSource for the source name, and correctly configure the errorformat. Other than %l & %c (line number & column), this requires %n which efm langserver uses to fill in the diagnostic code. You can also use efmls-configs-nvim to configure those linters for you.

[!IMPORTANT] Note that vim's errorformat only matches numbers for %n, which means it is not possible to parse diagnostic codes that consist of letters. One such case is the linter selene. To use those linters with nvim-rulebook you need to use nvim-lint which allows more flexible parsing.

lua -- example: configuring efm langserver for `markdownlint` in `/lsp/efm.lua` return { filetypes = { "markdown" }, settings = { languages = { markdown = { { lintSource = "markdownlint", lintCommand = "markdownlint $'{INPUT}'", lintStdin = false, lintIgnoreExitCode = true, lintFormats = { "%f:%l:%c MD%n/%m", "%f:%l MD%n/%m", }, }, }, }, }, }

How to directly ask an LLM about a rule

To ask an LLM about a rule, use a URL that opens a chat it for ruleDocs.fallback.

For ruleDocs.fallback, the %s placeholder will be replaced with the diagnostic source and the quoted code (or message, if no code is available), both URL-encoded.

```lua -- example to use ChatGPT for rule lookup require("rulebook").setup = ({ ruleDocs = { fallback = "https://chatgpt.com/?q=Explain%20the%20following%20diagnostic%20error%3A%20%s"

    -- To use `fallback` instead of the builtin rule docs, overwrite the
    -- builtin one with `false`.
    typescript = false,
}

}) ```

How to display the availability of rule lookup

The function require("rulebook").hasDocs(diag), expects a diagnostic object and returns a boolean whether nvim-rulebook documentation for the respective diagnostic available. One use case for this is to add a visual indicator if there is a rule lookup available for a diagnostic (see vim.diagnostic.config).

lua vim.diagnostic.config { virtual_text = { suffix = function(diag) return require("rulebook").hasDocs(diag) and "  " or "" end, }, }

Credits

In my day job, I am a sociologist studying the social mechanisms underlying the digital economy. For my PhD project, I investigate the governance of the app economy and how software ecosystems manage the tension between innovation and compatibility. If you are interested in this subject, feel free to get in touch.

Buy Me a Coffee at ko-fi.com

Owner

  • Name: Chris Grieser
  • Login: chrisgrieser
  • Kind: user
  • Location: Berlin, Germany
  • Company: Technical University of Berlin

Researcher in sociology & software developer

GitHub Events

Total
  • Issues event: 8
  • Watch event: 18
  • Delete event: 4
  • Issue comment event: 10
  • Push event: 119
  • Pull request review event: 1
  • Pull request review comment event: 1
  • Pull request event: 15
  • Fork event: 2
  • Create event: 4
Last Year
  • Issues event: 8
  • Watch event: 18
  • Delete event: 4
  • Issue comment event: 10
  • Push event: 119
  • Pull request review event: 1
  • Pull request review comment event: 1
  • Pull request event: 15
  • Fork event: 2
  • Create event: 4

Committers

Last synced: 9 months ago

All Time
  • Total Commits: 301
  • Total Committers: 5
  • Avg Commits per committer: 60.2
  • Development Distribution Score (DDS): 0.017
Past Year
  • Commits: 116
  • Committers: 4
  • Avg Commits per committer: 29.0
  • Development Distribution Score (DDS): 0.034
Top Committers
Name Email Commits
Chris Grieser 7****r 296
dependabot[bot] 4****] 2
Popkornium18 4****8 1
Mat m****t@m****k 1
Ben Elan n****y@b****v 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 9 months ago

All Time
  • Total issues: 9
  • Total pull requests: 5
  • Average time to close issues: about 1 month
  • Average time to close pull requests: about 2 hours
  • Total issue authors: 5
  • Total pull request authors: 4
  • Average comments per issue: 2.67
  • Average comments per pull request: 1.0
  • Merged pull requests: 5
  • Bot issues: 0
  • Bot pull requests: 1
Past Year
  • Issues: 5
  • Pull requests: 4
  • Average time to close issues: about 4 hours
  • Average time to close pull requests: about 2 hours
  • Issue authors: 3
  • Pull request authors: 3
  • Average comments per issue: 2.2
  • Average comments per pull request: 1.0
  • Merged pull requests: 4
  • Bot issues: 0
  • Bot pull requests: 1
Top Authors
Issue Authors
  • Popkornium18 (3)
  • mrjones2014 (2)
  • 120ace (1)
  • wroyca (1)
  • aemonge (1)
Pull Request Authors
  • dependabot[bot] (6)
  • mrjones2014 (2)
  • Popkornium18 (2)
  • benelan (2)
Top Labels
Issue Labels
enhancement (5) bug (3) Stale (2)
Pull Request Labels
dependencies (6) github_actions (4)

Dependencies

.github/workflows/panvimdoc.yml actions
  • actions/checkout v2 composite
  • kdheepak/panvimdoc main composite
  • stefanzweifel/git-auto-commit-action v4 composite
.github/workflows/stale-bot.yml actions
  • actions/stale v8 composite
.github/workflows/stylua.yml actions
  • JohnnyMorganz/stylua-action v2 composite
  • actions/checkout v3 composite