bash-language-server
Advanced tools
Comparing version 1.4.0 to 1.4.1
# Bash Language Server | ||
## 1.4.1 | ||
* It's now possible to disable error reporting by setting the environment variable | ||
`HIGHLIGHT_PARSING_ERRORS` to `false`. | ||
## 1.4.0 | ||
@@ -4,0 +9,0 @@ |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -7,4 +15,6 @@ // tslint:disable:no-submodule-imports | ||
const Path = require("path"); | ||
const request = require("request-promise-native"); | ||
const tree_sitter_1 = require("tree-sitter"); | ||
const bash = require("tree-sitter-bash"); | ||
const URI = require("urijs"); | ||
const LSP = require("vscode-languageserver"); | ||
@@ -20,2 +30,3 @@ const array_1 = require("./util/array"); | ||
constructor() { | ||
this.uriToTextDocument = {}; | ||
this.uriToTreeSitterDocument = {}; | ||
@@ -55,3 +66,3 @@ // We need this to find the word at a given point etc. | ||
connection.console.log('Analyzing ' + uri); | ||
analyzer.analyze(uri, fs.readFileSync(absolute, 'utf8')); | ||
analyzer.analyze(uri, LSP.TextDocument.create(uri, 'shell', 1, fs.readFileSync(absolute, 'utf8'))); | ||
}); | ||
@@ -74,2 +85,44 @@ resolve(analyzer); | ||
} | ||
getExplainshellDocumentation({ pos, endpoint, }) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const leafNode = this.uriToTreeSitterDocument[pos.textDocument.uri].rootNode.descendantForPosition({ | ||
row: pos.position.line, | ||
column: pos.position.character, | ||
}); | ||
// explainshell needs the whole command, not just the "word" (tree-sitter | ||
// parlance) that the user hovered over. A relatively successful heuristic | ||
// is to simply go up one level in the AST. If you go up too far, you'll | ||
// start to include newlines, and explainshell completely balks when it | ||
// encounters newlines. | ||
const interestingNode = leafNode.type === 'word' ? leafNode.parent : leafNode; | ||
const cmd = this.uriToFileContent[pos.textDocument.uri].slice(interestingNode.startIndex, interestingNode.endIndex); | ||
const explainshellResponse = yield request({ | ||
uri: URI(endpoint) | ||
.path('/api/explain') | ||
.addQuery('cmd', cmd) | ||
.toString(), | ||
json: true, | ||
}); | ||
// Attaches debugging information to the return value (useful for logging to | ||
// VS Code output). | ||
const response = Object.assign({}, explainshellResponse, { cmd, cmdType: interestingNode.type }); | ||
if (explainshellResponse.status === 'error') { | ||
return response; | ||
} | ||
else if (!explainshellResponse.matches) { | ||
return Object.assign({}, response, { status: 'error' }); | ||
} | ||
else { | ||
const offsetOfMousePointerInCommand = this.uriToTextDocument[pos.textDocument.uri].offsetAt(pos.position) - | ||
interestingNode.startIndex; | ||
const match = explainshellResponse.matches.find(helpItem => helpItem.start <= offsetOfMousePointerInCommand && | ||
offsetOfMousePointerInCommand < helpItem.end); | ||
const helpHTML = match && match.helpHTML; | ||
if (!helpHTML) { | ||
return Object.assign({}, response, { status: 'error' }); | ||
} | ||
return Object.assign({}, response, { helpHTML }); | ||
} | ||
}); | ||
} | ||
/** | ||
@@ -137,3 +190,4 @@ * Find all the locations where something named name has been defined. | ||
*/ | ||
analyze(uri, contents) { | ||
analyze(uri, document) { | ||
const contents = document.getText(); | ||
const d = new tree_sitter_1.Document(); | ||
@@ -143,2 +197,3 @@ d.setLanguage(bash); | ||
d.parse(); | ||
this.uriToTextDocument[uri] = document; | ||
this.uriToTreeSitterDocument[uri] = d; | ||
@@ -145,0 +200,0 @@ this.uriToDeclarations[uri] = {}; |
@@ -12,2 +12,3 @@ "use strict"; | ||
const LSP = require("vscode-languageserver"); | ||
const TurndownService = require("turndown"); | ||
const analyser_1 = require("./analyser"); | ||
@@ -51,8 +52,10 @@ const Builtins = require("./builtins"); | ||
const uri = change.document.uri; | ||
const contents = change.document.getText(); | ||
const diagnostics = this.analyzer.analyze(uri, contents); | ||
connection.sendDiagnostics({ | ||
uri: change.document.uri, | ||
diagnostics, | ||
}); | ||
const diagnostics = this.analyzer.analyze(uri, change.document); | ||
// Add guard | ||
if (process.env.HIGHLIGHT_PARSING_ERRORS !== 'false') { | ||
connection.sendDiagnostics({ | ||
uri: change.document.uri, | ||
diagnostics, | ||
}); | ||
} | ||
}); | ||
@@ -90,23 +93,40 @@ // Register all the handlers for the LSP events. | ||
onHover(pos) { | ||
const word = this.getWordAtPoint(pos); | ||
this.connection.console.log(`Hovering over ${pos.position.line}:${pos.position.character} - ${word}`); | ||
if (Builtins.isBuiltin(word)) { | ||
return Builtins.documentation(word).then(doc => ({ | ||
contents: { | ||
language: 'plaintext', | ||
value: doc, | ||
}, | ||
})); | ||
} | ||
else if (this.executables.isExecutableOnPATH(word)) { | ||
return this.executables.documentation(word).then(doc => ({ | ||
contents: { | ||
language: 'plaintext', | ||
value: doc, | ||
}, | ||
})); | ||
} | ||
else { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.connection.console.log(`Hovering over ${pos.position.line}:${pos.position.character}`); | ||
const word = this.getWordAtPoint(pos); | ||
if (process.env.EXPLAINSHELL_ENDPOINT !== '') { | ||
const response = yield this.analyzer.getExplainshellDocumentation({ | ||
pos, | ||
endpoint: process.env.EXPLAINSHELL_ENDPOINT, | ||
}); | ||
if (response.status === 'error') { | ||
this.connection.console.log('getExplainshellDocumentation returned: ' + JSON.stringify(response, null, 4)); | ||
} | ||
else { | ||
return { | ||
contents: { | ||
kind: 'markdown', | ||
value: new TurndownService().turndown(response.helpHTML), | ||
}, | ||
}; | ||
} | ||
} | ||
if (Builtins.isBuiltin(word)) { | ||
return Builtins.documentation(word).then(doc => ({ | ||
contents: { | ||
language: 'plaintext', | ||
value: doc, | ||
}, | ||
})); | ||
} | ||
if (this.executables.isExecutableOnPATH(word)) { | ||
return this.executables.documentation(word).then(doc => ({ | ||
contents: { | ||
language: 'plaintext', | ||
value: doc, | ||
}, | ||
})); | ||
} | ||
return null; | ||
} | ||
}); | ||
} | ||
@@ -113,0 +133,0 @@ onDefinition(pos) { |
@@ -6,3 +6,3 @@ { | ||
"license": "MIT", | ||
"version": "1.4.0", | ||
"version": "1.4.1", | ||
"publisher": "mads-hartmann", | ||
@@ -9,0 +9,0 @@ "main": "out/server.js", |
@@ -58,6 +58,8 @@ import * as LSP from 'vscode-languageserver' | ||
const diagnostics = this.analyzer.analyze(uri, change.document) | ||
connection.sendDiagnostics({ | ||
uri: change.document.uri, | ||
diagnostics, | ||
}) | ||
if (process.env.HIGHLIGHT_PARSING_ERRORS !== 'false') { | ||
connection.sendDiagnostics({ | ||
uri: change.document.uri, | ||
diagnostics, | ||
}) | ||
} | ||
}) | ||
@@ -64,0 +66,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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances 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
136106
1791
7