bash-language-server
Advanced tools
Comparing version 4.6.0 to 4.6.1
# Bash Language Server | ||
## 4.6.1 | ||
- Fix the ShellCheck code action feature that for some clients did not return any code actions. https://github.com/bash-lsp/bash-language-server/pull/700 | ||
## 4.6.0 | ||
@@ -4,0 +8,0 @@ |
@@ -290,24 +290,8 @@ "use strict"; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const codeActions = this.uriToCodeActions[params.textDocument.uri]; | ||
if (!codeActions) { | ||
return []; | ||
} | ||
const getDiagnosticsFingerPrint = (diagnostics) => (diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.map(({ code, source, range }) => code !== undefined && source && range | ||
? JSON.stringify({ | ||
code, | ||
source, | ||
range, | ||
}) | ||
: null).filter((fingerPrint) => fingerPrint != null)) || []; | ||
const paramsDiagnosticsKeys = getDiagnosticsFingerPrint(params.context.diagnostics); | ||
// find actions that match the paramsDiagnosticsKeys | ||
const actions = codeActions.filter((action) => { | ||
const actionDiagnosticsKeys = getDiagnosticsFingerPrint(action.diagnostics); | ||
// actions without diagnostics are always returned | ||
if (actionDiagnosticsKeys.length === 0) { | ||
return true; | ||
} | ||
return actionDiagnosticsKeys.some((actionDiagnosticKey) => paramsDiagnosticsKeys.includes(actionDiagnosticKey)); | ||
}); | ||
return actions; | ||
const codeActionsForUri = this.uriToCodeActions[params.textDocument.uri] || {}; | ||
const codeActions = params.context.diagnostics | ||
.map(({ data }) => codeActionsForUri[data === null || data === void 0 ? void 0 : data.id]) | ||
.filter((action) => action != null); | ||
logger_1.logger.debug(`onCodeAction: found ${codeActions.length} code action(s)`); | ||
return codeActions; | ||
}); | ||
@@ -314,0 +298,0 @@ } |
@@ -7,5 +7,5 @@ import * as LSP from 'vscode-languageserver/node'; | ||
}; | ||
type LintingResult = { | ||
export type LintingResult = { | ||
diagnostics: LSP.Diagnostic[]; | ||
codeActions: LSP.CodeAction[]; | ||
codeActions: Record<string, LSP.CodeAction | undefined>; | ||
}; | ||
@@ -12,0 +12,0 @@ export declare class Linter { |
@@ -37,3 +37,3 @@ "use strict"; | ||
if (!this._canLint) { | ||
return { diagnostics: [], codeActions: [] }; | ||
return { diagnostics: [], codeActions: {} }; | ||
} | ||
@@ -58,3 +58,3 @@ const { uri } = document; | ||
// We found a dialect that isn't supported by ShellCheck. | ||
return { diagnostics: [], codeActions: [] }; | ||
return { diagnostics: [], codeActions: {} }; | ||
} | ||
@@ -69,3 +69,3 @@ // NOTE: that ShellCheck actually does shebang parsing, but we manually | ||
if (!this._canLint) { | ||
return { diagnostics: [], codeActions: [] }; | ||
return { diagnostics: [], codeActions: {} }; | ||
} | ||
@@ -136,14 +136,14 @@ // Clean up the debounced function | ||
exports.Linter = Linter; | ||
function mapShellCheckResult({ uri, result, }) { | ||
function mapShellCheckResult({ uri, result }) { | ||
const diagnostics = []; | ||
const codeActions = []; | ||
const codeActions = {}; | ||
for (const comment of result.comments) { | ||
const start = { | ||
const range = LSP.Range.create({ | ||
line: comment.line - 1, | ||
character: comment.column - 1, | ||
}; | ||
const end = { | ||
}, { | ||
line: comment.endLine - 1, | ||
character: comment.endColumn - 1, | ||
}; | ||
}); | ||
const id = `shellcheck|${comment.code}|${range.start.line}:${range.start.character}-${range.end.line}:${range.end.character}`; | ||
const diagnostic = { | ||
@@ -154,3 +154,3 @@ message: comment.message, | ||
source: 'shellcheck', | ||
range: LSP.Range.create(start, end), | ||
range, | ||
codeDescription: { | ||
@@ -160,3 +160,5 @@ href: `https://www.shellcheck.net/wiki/SC${comment.code}`, | ||
tags: config_1.CODE_TO_TAGS[comment.code], | ||
// NOTE: we could use the 'data' property this enable easier fingerprinting | ||
data: { | ||
id, | ||
}, | ||
}; | ||
@@ -170,3 +172,3 @@ diagnostics.push(diagnostic); | ||
if (codeAction) { | ||
codeActions.push(codeAction); | ||
codeActions[id] = codeAction; | ||
} | ||
@@ -173,0 +175,0 @@ } |
@@ -6,3 +6,3 @@ { | ||
"license": "MIT", | ||
"version": "4.6.0", | ||
"version": "4.6.1", | ||
"main": "./out/server.js", | ||
@@ -18,3 +18,3 @@ "typings": "./out/server.d.ts", | ||
"engines": { | ||
"node": ">=14.0.0" | ||
"node": ">=14.18.0" | ||
}, | ||
@@ -21,0 +21,0 @@ "dependencies": { |
@@ -180,26 +180,27 @@ import * as Process from 'node:child_process' | ||
expect(fixableDiagnostic).toMatchInlineSnapshot(` | ||
Object { | ||
"code": "SC2086", | ||
"codeDescription": Object { | ||
"href": "https://www.shellcheck.net/wiki/SC2086", | ||
}, | ||
"message": "Double quote to prevent globbing and word splitting.", | ||
"range": Object { | ||
"end": Object { | ||
"character": 13, | ||
"line": 55, | ||
}, | ||
"start": Object { | ||
"character": 5, | ||
"line": 55, | ||
}, | ||
}, | ||
"severity": 3, | ||
"source": "shellcheck", | ||
"tags": undefined, | ||
} | ||
`) | ||
Object { | ||
"code": "SC2086", | ||
"codeDescription": Object { | ||
"href": "https://www.shellcheck.net/wiki/SC2086", | ||
}, | ||
"data": Object { | ||
"id": "shellcheck|2086|55:5-55:13", | ||
}, | ||
"message": "Double quote to prevent globbing and word splitting.", | ||
"range": Object { | ||
"end": Object { | ||
"character": 13, | ||
"line": 55, | ||
}, | ||
"start": Object { | ||
"character": 5, | ||
"line": 55, | ||
}, | ||
}, | ||
"severity": 3, | ||
"source": "shellcheck", | ||
"tags": undefined, | ||
} | ||
`) | ||
// TODO: we could find the diagnostics and then use the range to test the code action | ||
const onCodeAction = connection.onCodeAction.mock.calls[0][0] | ||
@@ -206,0 +207,0 @@ |
@@ -7,3 +7,2 @@ import { spawnSync } from 'node:child_process' | ||
import * as LSP from 'vscode-languageserver/node' | ||
import { CodeAction } from 'vscode-languageserver/node' | ||
import { TextDocument } from 'vscode-languageserver-textdocument' | ||
@@ -17,3 +16,3 @@ | ||
import * as ReservedWords from './reserved-words' | ||
import { Linter } from './shellcheck' | ||
import { Linter, LintingResult } from './shellcheck' | ||
import { SNIPPETS } from './snippets' | ||
@@ -42,3 +41,5 @@ import { BashCompletionItem, CompletionItemDataType } from './types' | ||
private workspaceFolder: string | null | ||
private uriToCodeActions: { [uri: string]: CodeAction[] | undefined } = {} | ||
private uriToCodeActions: { | ||
[uri: string]: LintingResult['codeActions'] | undefined | ||
} = {} | ||
@@ -391,37 +392,11 @@ private constructor({ | ||
private async onCodeAction(params: LSP.CodeActionParams): Promise<LSP.CodeAction[]> { | ||
const codeActions = this.uriToCodeActions[params.textDocument.uri] | ||
const codeActionsForUri = this.uriToCodeActions[params.textDocument.uri] || {} | ||
if (!codeActions) { | ||
return [] | ||
} | ||
const codeActions = params.context.diagnostics | ||
.map(({ data }) => codeActionsForUri[data?.id]) | ||
.filter((action): action is LSP.CodeAction => action != null) | ||
const getDiagnosticsFingerPrint = (diagnostics?: LSP.Diagnostic[]): string[] => | ||
diagnostics | ||
?.map(({ code, source, range }) => | ||
code !== undefined && source && range | ||
? JSON.stringify({ | ||
code, | ||
source, | ||
range, | ||
}) | ||
: null, | ||
) | ||
.filter((fingerPrint): fingerPrint is string => fingerPrint != null) || [] | ||
logger.debug(`onCodeAction: found ${codeActions.length} code action(s)`) | ||
const paramsDiagnosticsKeys = getDiagnosticsFingerPrint(params.context.diagnostics) | ||
// find actions that match the paramsDiagnosticsKeys | ||
const actions = codeActions.filter((action) => { | ||
const actionDiagnosticsKeys = getDiagnosticsFingerPrint(action.diagnostics) | ||
// actions without diagnostics are always returned | ||
if (actionDiagnosticsKeys.length === 0) { | ||
return true | ||
} | ||
return actionDiagnosticsKeys.some((actionDiagnosticKey) => | ||
paramsDiagnosticsKeys.includes(actionDiagnosticKey), | ||
) | ||
}) | ||
return actions | ||
return codeActions | ||
} | ||
@@ -428,0 +403,0 @@ |
@@ -57,3 +57,3 @@ import * as path from 'path' | ||
expect(result).toEqual({ | ||
codeActions: [], | ||
codeActions: {}, | ||
diagnostics: [], | ||
@@ -80,4 +80,4 @@ }) | ||
Object { | ||
"codeActions": Array [ | ||
Object { | ||
"codeActions": Object { | ||
"shellcheck|2086|1:5-1:9": Object { | ||
"diagnostics": Array [ | ||
@@ -89,2 +89,5 @@ Object { | ||
}, | ||
"data": Object { | ||
"id": "shellcheck|2086|1:5-1:9", | ||
}, | ||
"message": "Double quote to prevent globbing and word splitting.", | ||
@@ -141,3 +144,3 @@ "range": Object { | ||
}, | ||
], | ||
}, | ||
"diagnostics": Array [ | ||
@@ -149,2 +152,5 @@ Object { | ||
}, | ||
"data": Object { | ||
"id": "shellcheck|2154|1:5-1:9", | ||
}, | ||
"message": "foo is referenced but not assigned.", | ||
@@ -170,2 +176,5 @@ "range": Object { | ||
}, | ||
"data": Object { | ||
"id": "shellcheck|2086|1:5-1:9", | ||
}, | ||
"message": "Double quote to prevent globbing and word splitting.", | ||
@@ -206,3 +215,3 @@ "range": Object { | ||
expect(result).toEqual({ | ||
codeActions: [], | ||
codeActions: {}, | ||
diagnostics: [], | ||
@@ -219,3 +228,3 @@ }) | ||
expect(result).toEqual({ | ||
codeActions: [], | ||
codeActions: {}, | ||
diagnostics: [], | ||
@@ -233,3 +242,3 @@ }) | ||
Object { | ||
"codeActions": Array [], | ||
"codeActions": Object {}, | ||
"diagnostics": Array [ | ||
@@ -241,2 +250,5 @@ Object { | ||
}, | ||
"data": Object { | ||
"id": "shellcheck|1091|3:7-3:19", | ||
}, | ||
"message": "Not following: shellcheck/sourced.sh: openBinaryFile: does not exist (No such file or directory)", | ||
@@ -262,2 +274,5 @@ "range": Object { | ||
}, | ||
"data": Object { | ||
"id": "shellcheck|2154|5:6-5:10", | ||
}, | ||
"message": "foo is referenced but not assigned.", | ||
@@ -290,3 +305,3 @@ "range": Object { | ||
expect(result).toEqual({ | ||
codeActions: [], | ||
codeActions: {}, | ||
diagnostics: [], | ||
@@ -293,0 +308,0 @@ }) |
@@ -26,5 +26,5 @@ import { dirname } from 'node:path' | ||
type LintingResult = { | ||
export type LintingResult = { | ||
diagnostics: LSP.Diagnostic[] | ||
codeActions: LSP.CodeAction[] | ||
codeActions: Record<string, LSP.CodeAction | undefined> | ||
} | ||
@@ -57,3 +57,3 @@ | ||
if (!this._canLint) { | ||
return { diagnostics: [], codeActions: [] } | ||
return { diagnostics: [], codeActions: {} } | ||
} | ||
@@ -85,3 +85,3 @@ | ||
// We found a dialect that isn't supported by ShellCheck. | ||
return { diagnostics: [], codeActions: [] } | ||
return { diagnostics: [], codeActions: {} } | ||
} | ||
@@ -105,3 +105,3 @@ | ||
if (!this._canLint) { | ||
return { diagnostics: [], codeActions: [] } | ||
return { diagnostics: [], codeActions: {} } | ||
} | ||
@@ -187,25 +187,20 @@ | ||
function mapShellCheckResult({ | ||
uri, | ||
result, | ||
}: { | ||
uri: string | ||
result: ShellCheckResult | ||
}): { | ||
diagnostics: LSP.Diagnostic[] | ||
codeActions: LSP.CodeAction[] | ||
} { | ||
const diagnostics: LSP.Diagnostic[] = [] | ||
const codeActions: LSP.CodeAction[] = [] | ||
function mapShellCheckResult({ uri, result }: { uri: string; result: ShellCheckResult }) { | ||
const diagnostics: LintingResult['diagnostics'] = [] | ||
const codeActions: LintingResult['codeActions'] = {} | ||
for (const comment of result.comments) { | ||
const start: LSP.Position = { | ||
line: comment.line - 1, | ||
character: comment.column - 1, | ||
} | ||
const end: LSP.Position = { | ||
line: comment.endLine - 1, | ||
character: comment.endColumn - 1, | ||
} | ||
const range = LSP.Range.create( | ||
{ | ||
line: comment.line - 1, | ||
character: comment.column - 1, | ||
}, | ||
{ | ||
line: comment.endLine - 1, | ||
character: comment.endColumn - 1, | ||
}, | ||
) | ||
const id = `shellcheck|${comment.code}|${range.start.line}:${range.start.character}-${range.end.line}:${range.end.character}` | ||
const diagnostic: LSP.Diagnostic = { | ||
@@ -216,3 +211,3 @@ message: comment.message, | ||
source: 'shellcheck', | ||
range: LSP.Range.create(start, end), | ||
range, | ||
codeDescription: { | ||
@@ -222,3 +217,5 @@ href: `https://www.shellcheck.net/wiki/SC${comment.code}`, | ||
tags: CODE_TO_TAGS[comment.code], | ||
// NOTE: we could use the 'data' property this enable easier fingerprinting | ||
data: { | ||
id, | ||
}, | ||
} | ||
@@ -235,3 +232,3 @@ | ||
if (codeAction) { | ||
codeActions.push(codeAction) | ||
codeActions[id] = codeAction | ||
} | ||
@@ -238,0 +235,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
962177
9512