LSP: can't get eslint working

Hey,

I am trying to get the eslint server working, but to no avail. I have tried the vscode-eslint server as seen in an example config (although vscode-eslint is not on npm), and I have tried several versions of the eslint server that takes the --stdin value.

The server is started, but my code doesn’t seem to output the eslint errors that I have configured to display with running eslint manually.

  • OS and language server: I’ve tried it both on OSX and Linux (WSL).
  • How you installed LSP (Package Control or from git?): LSP was installed in sublime from package control
  • Minimal reproduction steps: Just try to get eslint working … you can’t

an example config for eslint-server:

			"eslint":
			{
				"enabled": true,
				"command":
				[
					"node",
					"/home/karolyi/Work/private/project/node_modules/eslint-server/lib/index.js",
					"--stdio"
				],
			},

  • Log
LSP: global configs ['reason=False', 'lsp-tsserver=False', 'rls=False', 'pyls=True', 'cquery=False', 'polymer-ide=False', 'clangd=False', 'haskell-ide-engine=False', 'jdtls=False', 'ocaml=False', 'golsp=False', 'eslint=False', 'typescript-language-server=False', 'javascript-typescript-langserver=False', 'phpls=False']
LSP: window 2 has override for pyls {'command': ['/home/karolyi/Work/private/project/venv/bin/pyls'], 'languageId': 'python', 'syntaxes': ['Packages/Python/Python.sublime-syntax', 'Packages/Djaneiro/Syntaxes/Python Django.tmLanguage'], 'enabled': True, 'scopes': ['source.python']}
LSP: window 2 has override for eslint {'command': ['node', '/home/karolyi/Work/private/project/node_modules/eslint-server/lib/index.js', '--stdio'], 'enabled': True}
LSP: window 2 starting 1 initial views
LSP: window 2 requests eslint for /home/karolyi/Work/private/project/frontend/src/js/shop/sign-up.js
LSP: starting in /home/karolyi/Work/private/project
LSP: starting ['node', '/home/karolyi/Work/private/project/node_modules/eslint-server/lib/index.js', '--stdio']
LSP:  --> initialize
LSP: window 2 added session eslint
LSP:      {'capabilities': {'codeActionProvider': True, 'textDocumentSync': {'change': 1, 'willSaveWaitUntil': True, 'openClose': True, 'save': {'includeText': False}}, 'executeCommandProvider': {'commands': ['eslint.applySingleFix', 'eslint.applySameFixes', 'eslint.applyAllFixes', 'eslint.applyAutoFix']}}}
LSP:  --> initialized
LSP:  --> textDocument/didOpen
LSP: <--  client/registerCapability
LSP:      {'registrations': [{'id': 'c697f786-6386-45a0-8503-adc31f5422bc', 'registerOptions': {}, 'method': 'workspace/didChangeConfiguration'}]}
LSP: Unhandled request client/registerCapability
LSP: <--  workspace/configuration
LSP:      {'items': [{'scopeUri': 'file:///home/karolyi/Work/private/project/frontend/src/js/shop/sign-up.js', 'section': ''}]}
LSP: Unhandled request workspace/configuration
LSP:  --> textDocument/didSave

Would there be a way for you to integrate https://github.com/tbodt/js-langserver ? It uses tern and eslint the same time, which would be perfect.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 22 (12 by maintainers)

Most upvoted comments

Topic changed from eslint-server to js-langserver but I’ll go back to initial problem and question:

Could you figure out what VSCode does in case it receives a workspace/configuration request from eslint?

I’ve checked that:


[Trace - 10:29:36 PM] Received request 'workspace/configuration - (2)'.
Params: {
    "items": [
        {
            "scopeUri": "file:///Users/foo/workspace/dynamodb-admin/lib/actions/purgeTable.js",
            "section": ""
        }
    ]
}


[Trace - 10:29:36 PM] Sending response 'workspace/configuration - (2)'. Processing request took 2ms
Result: [
    {
        "validate": true,
        "packageManager": "npm",
        "autoFix": true,
        "autoFixOnSave": false,
        "options": {},
        "run": "onType",
        "nodePath": null,
        "workspaceFolder": {
            "name": "dynamodb-admin",
            "uri": "file:///Users/foo/workspace/dynamodb-admin"
        },
        "codeAction": {
            "disableRuleComment": {
                "enable": true,
                "location": "newLine"
            },
            "showDocumentation": {
                "enable": true
            }
        }
    }
]

Here is the code that sends the response: https://github.com/Microsoft/vscode-eslint/blob/ff75d429be69ec09237ee859343739768f6c4a6d/client/src/extension.ts#L470

And here is, I think, the code that validates response: https://github.com/Microsoft/vscode-eslint/blob/ff75d429be69ec09237ee859343739768f6c4a6d/server/src/eslintServer.ts#L416

It seems that LSP would need to send pretty much the same response for server not to break but I haven’t verified if that’s all that is needed.

(It would probably be best to split this discussion into two bugs, one for each LS.)

@predragnikolic

Sure thing mate, here are my configs, I’ve included literally everything I can think of for this. Let me know how you go.

Sublime Text packages:

Babel v8.6.3
LSP v0.9.0
TypeScript Syntax v0.0.29

Directory structure:

$ pwd
/path/to/some_node_project
$ tree -L 1
├── babel.config.js
├── node_modules
├── package-lock.json
├── package.json
├── index.ts
└── tsconfig.json

Global NPM install

$ npm list -g --depth=0
├── npm@6.11.3
├── ts-node@8.3.0
├── typescript@3.5.3
└── typescript-language-server@0.4.0

tsconfig.json

{
  "compilerOptions": {
    "rootDir": "./",
    "baseUrl": "./",
    "target": "es6",
    "module": "commonjs",
    "lib": [
      "es2018",
      "esnext.asynciterable",
      "esnext.array"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "plugins": [
      {
        "name": "typescript-eslint-language-service"
      }
    ]
  },
  "include": [
    "**/**/**.ts",
    "**/*.d.ts"
  ],
  "typeRoots": [
    "**/*.d.ts"
  ],
  "exclude": [
    "node_modules",
    "**/node_modules/**",
    "**/*.spec.ts",
    "dist"
  ]
}

.eslintrc.js

module.exports = {
  env: {
    browser: false,                                               // make true if react
    node: true
  },
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.ts', '.js']                                // add '.tsx' if react
      }
    }
  },
  parser: '@typescript-eslint/parser',                            // you could use... 'babel-eslint'... but nah
  parserOptions: {
    ecmaVersion: 2018,                                            // modern features
    sourceType: 'module',                                         // allow use of node modules `import` and `export`
    project: './tsconfig.json',                                   // typescript rule settings
    tsconfigRootDir: __dirname,
    createDefaultProgram: true
  },
  extends: [
    'plugin:@typescript-eslint/recommended',                      // ootb eslint recommends
    'standard'                                                    // ootb standardjs
    // 'standard-jsx'                                                // ootb standardjs-jsx
  ],
  plugins: [
    '@typescript-eslint'                                          // allows override via rules below
    // 'react-hooks'
  ],
  rules: {
    // 'react-hooks/rules-of-hooks': 'error',
    // 'react-hooks/exhaustive-deps': 'warn',
    '@typescript-eslint/no-use-before-define': ['error', {        // hoist functions (not variables)
      "functions": false
    }],
    '@typescript-eslint/no-explicit-any': 'off',                  // sometimes we need to jerry-rig
    '@typescript-eslint/explicit-function-return-type': 'off',
    '@typescript-eslint/interface-name-prefix': 'off',            // use our own prefix
    '@typescript-eslint/member-delimiter-style': ['error', {      // no delimiters for interfaces
      multiline: {
        'delimiter': 'none',
        'requireLast': false
      },
      singleline: {
        'delimiter': 'comma',
        'requireLast': false
      }
    }],
    '@typescript-eslint/indent': 'off',                           // standardjs is doing this instead
    'camelcase': 'off',                                           // & 3 below, graphql calls to postgres require snake_case
    '@typescript-eslint/camelcase': ['error', {                   // as it's postgres' convention.
      'ignoreDestructuring': true
    }],
    'no-unused-vars': 'off',
    'node/no-unsupported-features/es-syntax': 'off'               // allows use of `import` and `export`
  }
}

LSP settings, user

{
  "auto_show_diagnostics_panel_level": 3,
  "clients":
  {
    "bashls":
    {
      "enabled": false
    },
    "js-ls": {
      "enabled": true,
      "command": [
        "typescript-language-server",
        "--stdio"
      ],
      "languageId": "javascript",
      "scopes": [
        "source.js"
      ],
      "syntaxes": [
        "Packages/Babel/JavaScript (Babel).sublime-syntax",
      ]
    },
    "ts-ls":
    {
      "enabled": true,
      "command": [
        "typescript-language-server",
        "--stdio"
      ],
      "languageId": [
        "typescript",
        "typescriptreact"
      ],
      "scopes": [
        "source.ts",
        "source.tsx"
      ],
      "syntaxes": [
        "Packages/TypeScript Syntax/TypeScript.tmLanguage",
        "Packages/TypeScript Syntax/TypeScriptReact.tmLanguage"
      ]
    },
    "vscode-css":
    {
      "enabled": true
    }
  },
  "completion_hint_type": "kind",
  "log_debug": true,
  "log_server": true,
  "log_payloads": false,
  "only_show_lsp_completions": true,
  "show_diagnostics_count_in_view_status": true,
  "show_diagnostics_phantoms": false,
  "show_references_in_quick_panel": true,
  "show_view_status": true
}

babel.config.js

module.exports = (api) => {
  api.cache(false)

  const presets = ['@babel/preset-env']
  const plugins = [
    ["@babel/plugin-transform-runtime",
      {
        "regenerator": true
      }
    ]
  ]

  return {
    presets,
    plugins
  }
}

Package.json

{
  "name": "thing",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@babel/runtime": "^7.6.0"
  },
  "devDependencies": {
    "@babel/cli": "^7.5.0",
    "@babel/core": "^7.5.0",
    "@babel/node": "^7.6.1",
    "@babel/plugin-transform-runtime": "^7.6.0",
    "@babel/preset-env": "^7.5.0",
    "@types/node": "^12.7.2",
    "@typescript-eslint/eslint-plugin": "^2.0.0",
    "@typescript-eslint/parser": "2.0.0",
    "eslint": "^6.4.0",
    "eslint-config-standard": "^13.0.1",
    "eslint-plugin-import": "^2.18.2",
    "eslint-plugin-node": "^9.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.0",
    "ts-node": "^8.4.1",
    "typescript": "^3.5.3",
    "typescript-eslint-language-service": "^1.4.0"
  }
}