• Stars
    star
    410
  • Rank 105,468 (Top 3 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 5 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

diagnostic language server integrate with linters

diagnostic-languageserver

General purpose Language Server that integrate with linter to support diagnostic features

Main features

  • diagnostic with linters
  • document format

screenshot with neovim and coc image

Install

yarn global add diagnostic-languageserver

make sure your yarn's global bin path is include in PATH

for example export PATH="$(yarn global bin):$PATH"

Config & Document

languageserver config:

{
  "languageserver": {
    "dls": {
      "command": "diagnostic-languageserver",
      "args": ["--stdio", "--log-level", "2"],
      "filetypes": [ "sh", "email" ], // filetypes that you want to enable this lsp
      "initializationOptions": {
        "linters": {
          ...
        },
        "filetypes": {
          ...
        },
        "formatters": {
          ...
        },
        "formatFiletypes": {
          ...
        }
      }
    }
  }
}

linters field:

{
  "linterName": {                                    // linter name, for example: vint
    "command": "shellcheck",                         // linter command
    "rootPatterns": [],                              // root patterns, default empty array
    "isStdout": true,                                // use stdout output, default true
    "isStderr": false,                               // use stderr output, default false
    "debounce": 100,                                 // debounce time
    "onSaveOnly": false,                             // linter is triggered only when file is saved
    "args": [ "--format=gcc", "-"],                  // args
    "offsetLine": 0,                                 // offsetline
    "offsetColumn": 0,                               // offsetColumn
    "sourceName": "shellcheck",                      // source name
    "ignore": [".git", "dist/"]                      // ignore pattern same as `.gitignore`
                                                     // don't forget to add `rootPatterns` when using `ignore`
                                                     // it need workspace to filter

    // Using regular expressions:
    "formatLines": 1,                                // how much lines for formatPattern[0] to match
    "formatPattern": [
      "^([^:]+):(\\d+):(\\d+):\\s+([^:]+):\\s+(.*)$",  // line match pattern (javascript regex)
      {
        "sourceName": 1,                             // diagnostic file use match group 1. Will default to the file being linted.
        "sourceNameFilter": true,                    // Display diagnostics only for the current file.
                                                     // Only works when sourceName is defined and when it contains either an absolute
                                                     // or relative path to the file being linted. Defaults to false.
        "line": 2,                                   // diagnostic line use match group 2
        "column": 3,                                 // diagnostic column use match group 3
        "endLine": 2,                                // diagnostic end line use match group 2. Will default to group from `line`
        "endColumn": 3,                              // diagnostic end column use match group 3. Will default to group from `column`
        "message": [5],                              // message to display use match group 5
        "security": 4                                // security to use match group 4, ignore if linter do not support security
      }
    ],

    // Using JSON:
    "parseJson": {
      "errorsRoot": "[0].messages",                  // dot separated path. Will default to whatever JSON is output
                                                     // for more information see examples at https://lodash.com/docs/#get
                                                     // %filepath will be replaced with full path to the file (like in `args`)

      // All of these support lodash.get syntax.
      "sourceName": "file",                          // propert that contains the `file`. Will default to the file being linted.
      "sourceNameFilter": true,                      // Display diagnostics only for the current file.
                                                     // Only works when sourceName is defined and when it contains either an absolute
                                                     // or relative path to the file being linted. Defaults to false.
      "line": "line",                                // property that contains the `line`
      "column": "column",                            // property that contains the `column`
      "endLine": "endLine",                          // property that contains the `endLine`. Will default to `line`
      "endColumn": "endColumn",                      // property that contains the `endColumn`. Will default to `column`
      "security": "severity",                        // property that contains the `security`
      "message": "${message} [${code}]",             // message to display
    },

    "securities": {                                  // security keys, ignore if linter do not support security
      "error": "error",                              // [key: string]?: "error" | "warning" | "info" | "hint"
      "warning": "warning",
      "note": "info"
    },
    "requiredFiles": [                               // only run linter if any of these files exist. option
      ".shellcheckrc",
      "shellcheckrc"
    ]
  }
}

filetypes field:

{
  "sh": "linterName",                          // filetype: linterName or linterName[]
  "*": "linterName"                            // `*` is for all filetypes
}

formatters field:

  "dartfmt": {                                 // formatter name
    "command": "dartfmt",                      // format command
    "args": [ "--fix" ],                       // args
    "rootPatterns": [],                        // root patterns, default empty array
    "isStdout": true,                          // use stdout output, default true
    "isStderr": false,                         // use stderr output, default false
    "doesWriteToFile": false,                  // use if formatter doesn't support stdio. should be paired with `%file`
    "requiredFiles": [                         // only run formatter if any of these files exist. optional
      ".run_dartfmt",
    ],
    "ignoreExitCode": false,                   // ignore exit code. default false: exit code > 0 will not change the file.
                                               // some formatter may exit with code > 0 so you need set it to true or number[]
                                               // exit code array that you want to ignore.
    "ignore": [".git", "dist/"]                // ignore pattern same as `.gitignore`
                                               // don't forget to add `rootPatterns` when using `ignore`
                                               // it need workspace to filter
  }

formatFiletypes field:

{
  "dart": "dartfmt",                          // filetype: formatterName or formatterName[]
  "*": "linterName"                           // `*` is for all filetypes
}

Args additional syntax

args: ["%text", "%filename", "%relativepath", "%file", "%filepath", "%dirname", "%tempfile"]

  • %filename will replace with basename of file
  • %text will replace with file content
  • %file will replace with full path to the file and not use stdio
  • %filepath will replace with full path to the file
  • %relativepath will replace with relative path of file
  • %dirname will replace with dirname of file
  • %tempfile will replace with the full path to a temporary file written with the contents of the document and not use stdio; this file will automatically be deleted when the command completes

How to config a new linter

shellcheck for example:

file test.sh:

#!/usr/bin/env bash

echo `ls -al`

then:

shellcheck --format=gcc test.sh

output:

t.sh:3:6: warning: Quote this to prevent word splitting. [SC2046]
t.sh:3:6: note: Useless echo? Instead of 'echo $(cmd)', just use 'cmd'. [SC2005]
t.sh:3:6: note: Use $(...) notation instead of legacy backticked `...`. [SC2006]

write pattern to match the line for line column message security:

const line = "t.sh:3:6: warning: Quote this to prevent word splitting. [SC2046]"
const formatPattern = "^[^:]+:(\\d+):(\\d+):\\s+([^:]+):\\s+(.*)$"
const match = line.match(new RegExp(formatPattern))
console.log(match)

output:

{
  0: "t.sh:3:6: warning: Quote this to prevent word splitting. [SC2046]"
  1: "3"
  2: "6"
  3: "warning"
  4: "Quote this to prevent word splitting. [SC2046]"
}

so you got:

  • line: match[1]
  • column: match[2]
  • message: match[4]
  • security: match[3]

and your formatPattern field will be:

"formatPattern": [
  "^[^:]+:(\\d+):(\\d+):\\s+([^:]+):\\s+(.*)$",    // line match pattern (javascript regex)
  {
    "line": 1,                                     // diagnostic line use match group 1
    "column": 2,                                   // diagnostic column use match group 2
    "message": [4],                                // message to display use match group 4
    "security": 3                                  // security to use match group 3, ignore if linter do not support security
  }
]

Notes if the linter's message for per issue more then one line, you have to set the formatLines to fill your pattern, and you can view the languagetool pattern for example which formatLines = 2

Example with coc.nvim

Each LSP client should support initializationOptions option, all you need for diagnostic-languageserver is put the config in initializationOptions option.

  1. shellcheck for shell
  2. languagetool for grammer check
  3. more Linters config example.

coc-settings.json:

you can use this extension https://github.com/iamcco/coc-diagnostic

{
  "languageserver": {
    "dls": {
      "command": "diagnostic-languageserver",
      "args": ["--stdio"],
      "filetypes": [ "sh", "email", "dart" ],
      "initializationOptions": {
        "linters": {
          "shellcheck": {
            "command": "shellcheck",
            "debounce": 100,
            "args": [ "--format=gcc", "-"],
            "offsetLine": 0,
            "offsetColumn": 0,
            "sourceName": "shellcheck",
            "formatLines": 1,
            "formatPattern": [
              "^[^:]+:(\\d+):(\\d+):\\s+([^:]+):\\s+(.*)$",
              {
                "line": 1,
                "column": 2,
                "message": 4,
                "security": 3
              }
            ],
            "securities": {
              "error": "error",
              "warning": "warning",
              "note": "info"
            }
          },
          "languagetool": {
            "command": "languagetool",
            "debounce": 200,
            "args": ["-"],
            "offsetLine": 0,
            "offsetColumn": 0,
            "sourceName": "languagetool",
            "formatLines": 2,
            "formatPattern": [
              "^\\d+?\\.\\)\\s+Line\\s+(\\d+),\\s+column\\s+(\\d+),\\s+([^\\n]+)\nMessage:\\s+(.*)$",
              {
                "line": 1,
                "column": 2,
                "message": [4, 3]
              }
            ],
          }
        },
        "formatters": {
          "dartfmt": {
            "command": "dartfmt",
            "args": [ "--fix" ],
          }
        },
        "filetypes": {
          "sh": "shellcheck",
          "email": "languagetool"
        },
        "formatFiletypes": {
          "dart": "dartfmt"
        }
      }
    }
  }
}

TODO

  • local node_modules linter support like eslint or textlint
  • diagnostic severity
  • root pattern
  • document format

References

Buy Me A Coffee ☕️

btc

image

More Repositories

1

markdown-preview.nvim

markdown preview plugin for (neo)vim
JavaScript
6,530
star
2

markdown-preview.vim

⚠️ PLEASE USE https://github.com/iamcco/markdown-preview.nvim INSTEAD
CSS
793
star
3

vim-language-server

VImScript language server, LSP for vim script
JavaScript
496
star
4

coc-flutter

flutter support for (Neo)vim
TypeScript
472
star
5

coc-tailwindcss

tailwindcss class name completion for (neo)vim
TypeScript
333
star
6

coc-spell-checker

A basic spell checker that works well with camelCase code for (Neo)vim
TypeScript
263
star
7

coc-diagnostic

diagnostic-languageserver extension for coc.nvim
TypeScript
246
star
8

coc-vimlsp

viml language server
TypeScript
211
star
9

coc-angular

Angular Language Service coc extension for (neo)vim
TypeScript
145
star
10

ds-pinyin-lsp

Dead Simple Pinyin Language Server
Rust
114
star
11

coc-actions

Actions menu for Neovim
TypeScript
102
star
12

coc-rainbow-fart

🌈 rainbow-fart for (neo)vim 一个在你编程时疯狂称赞你的 coc.nvim 扩展插件 | An coc.nvim extension that keeps giving you compliment while you are coding, it will checks the keywords of code to play suitable sounds.
TypeScript
84
star
13

dict.vim

vim简单的翻译工具
Python
74
star
14

markdown.css

markdown styles
CSS
60
star
15

coc-post

post extension for coc.nvim
TypeScript
55
star
16

dotfiles

my dotfiles
Vim Script
52
star
17

git-p.nvim

Git plus for (neo)vim
JavaScript
38
star
18

clock.nvim

A Big Clock For Neovim
JavaScript
33
star
19

coc-leetcode

leetcode 扩展
TypeScript
33
star
20

coc-svg

A Powerful SVG Language Support coc Extension for (neo)vim
TypeScript
31
star
21

async-await.lua

Write async function more like javascript async/await
Lua
28
star
22

coc-zi

look or google 10000 english for (neo)vim
TypeScript
28
star
23

coc-cspell-dicts

Ext spell dictionary extension for coc-spell-checker
TypeScript
21
star
24

coc-gitignore

gitignore extension for coc.nvim
TypeScript
20
star
25

mathjax-support-for-mkdp

mathjax support for markdown-preview.vim plugin
JavaScript
19
star
26

coc-project

project extension for coc.nvim
TypeScript
18
star
27

bg.workflow

追番,alfred3 workflow 查看每日新番
Python
10
star
28

Bencode

解析torrent文件
Python
9
star
29

coc-clock

clock for neovim
TypeScript
8
star
30

coc-webpack

Autocomplete support for webpack config
TypeScript
7
star
31

htom

convert html to markdown
JavaScript
4
star
32

iamcco.github.io

Too young Too simple Sometimes naive
HTML
3
star
33

manga-download

漫画下载
Python
3
star
34

sran.nvim

simple request and notification call for (neo)vim
JavaScript
3
star
35

denite-source.vim

denite source of denite sources
Python
3
star
36

gh-pages-webpack-plugin

gh-pages plugin for webpack
JavaScript
3
star
37

file-manager.vim

Denite source for file management
Python
3
star
38

statusline.vim

Vim Script
3
star
39

smartIM.nvim

smart IM for neovim
Python
2
star
40

yuuko

An hexo theme inspire by Time axis of Qzone
CSS
2
star
41

coc-bootstrap-classname

JavaScript
2
star
42

buzuo.vim

😱 buzuo(不做)list for vim/neovim
Vim Script
2
star
43

HomePage

My home page
JavaScript
2
star
44

next-theme

refind next theme dark
2
star
45

gitignore.vim

denite source for gitignore
Python
2
star
46

rxjs-operators

rxjs 操作符补完计划
TypeScript
2
star
47

go-to-file.vim

go to the file from require or import
Vim Script
2
star
48

md-it-mermaid

markdown-it plugin for mermaid
JavaScript
1
star
49

coc-action-source.nvim

CocAction source of coc.nvim
Python
1
star
50

nichijou

yuuko mio mai hakase nano sakamoto no monogatari
1
star
51

git-blame.vim

git blame
Vim Script
1
star
52

vimrc.backup

vimrc配置/字体等备份
Vim Script
1
star
53

BEND

JavaScript
1
star
54

exec-frequent

exec function frequent
JavaScript
1
star
55

redux-async-combine-reducers

Asynchronous add reducers
JavaScript
1
star
56

RotateGame

JavaScript
1
star
57

react-error-codes.vim

Denite sources for react error codes
Python
1
star
58

hello-dt

Using DevTerm as a print server
TypeScript
1
star
59

fzf-source.vim

denite source of fzf source for (neo)vim
Python
1
star
60

.github

1
star
61

float2

move the dot of float
JavaScript
1
star
62

rxh

RxJS hook for React with no magic
JavaScript
1
star
63

save-cloud-vita

PSVita 游戏存档云备份工具!
Rust
1
star