bash-language-server
Advanced tools
Comparing version 1.6.1 to 1.7.0
#!/usr/bin/env node | ||
/* eslint-disable no-console */ | ||
@@ -3,0 +4,0 @@ const server = require('../out/index') |
# Bash Language Server | ||
## 1.7.0 | ||
* Add PATH tilde expansion | ||
* Builtins and man pages formatting | ||
## 1.6.1 | ||
@@ -4,0 +9,0 @@ |
@@ -0,3 +1,3 @@ | ||
import * as LSP from 'vscode-languageserver'; | ||
import * as Parser from 'web-tree-sitter'; | ||
import * as LSP from 'vscode-languageserver'; | ||
/** | ||
@@ -15,3 +15,3 @@ * The Analyzer uses the Abstract Syntax Trees (ASTs) that are provided by | ||
*/ | ||
static fromRoot({connection, rootPath, parser}: { | ||
static fromRoot({ connection, rootPath, parser, }: { | ||
connection: LSP.Connection; | ||
@@ -32,3 +32,3 @@ rootPath: string | null; | ||
findDefinition(name: string): LSP.Location[]; | ||
getExplainshellDocumentation({pos, endpoint}: { | ||
getExplainshellDocumentation({ pos, endpoint, }: { | ||
pos: LSP.TextDocumentPositionParams; | ||
@@ -66,3 +66,3 @@ endpoint: string; | ||
wordAtPoint(uri: string, line: number, column: number): string | null; | ||
private symbolKindToCompletionKind(s); | ||
private symbolKindToCompletionKind; | ||
} |
@@ -11,3 +11,2 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// tslint:disable:no-submodule-imports | ||
const fs = require("fs"); | ||
@@ -35,2 +34,3 @@ const glob = require("glob"); | ||
// These keys are using underscores as that's the naming convention in tree-sitter. | ||
/* eslint-disable @typescript-eslint/camelcase */ | ||
environment_variable_assignment: LSP.SymbolKind.Variable, | ||
@@ -66,4 +66,4 @@ function_definition: LSP.SymbolKind.Function, | ||
if (fs.existsSync(absolute) && fs.lstatSync(absolute).isFile()) { | ||
const uri = 'file://' + absolute; | ||
connection.console.log('Analyzing ' + uri); | ||
const uri = `file://${absolute}`; | ||
connection.console.log(`Analyzing ${uri}`); | ||
analyzer.analyze(uri, LSP.TextDocument.create(uri, 'shell', 1, fs.readFileSync(absolute, 'utf8'))); | ||
@@ -101,2 +101,3 @@ } | ||
const cmd = this.uriToFileContent[pos.textDocument.uri].slice(interestingNode.startIndex, interestingNode.endIndex); | ||
// FIXME: type the response and unit test it | ||
const explainshellResponse = yield request({ | ||
@@ -121,3 +122,3 @@ uri: URI(endpoint) | ||
interestingNode.startIndex; | ||
const match = explainshellResponse.matches.find(helpItem => helpItem.start <= offsetOfMousePointerInCommand && | ||
const match = explainshellResponse.matches.find((helpItem) => helpItem.start <= offsetOfMousePointerInCommand && | ||
offsetOfMousePointerInCommand < helpItem.end); | ||
@@ -124,0 +125,0 @@ const helpHTML = match && match.helpHTML; |
@@ -14,3 +14,3 @@ /** | ||
*/ | ||
list(): Array<string>; | ||
list(): string[]; | ||
/** | ||
@@ -17,0 +17,0 @@ * Check if the the given {{executable}} exists on the PATH |
@@ -56,2 +56,3 @@ "use strict"; | ||
function findExecutablesInPath(path) { | ||
path = FsUtil.untildify(path); | ||
return new Promise((resolve, _) => { | ||
@@ -58,0 +59,0 @@ Fs.lstat(path, (err, stat) => { |
@@ -5,3 +5,2 @@ 'use strict'; | ||
const server_1 = require("./server"); | ||
// tslint:disable-next-line:no-var-requires | ||
const pkg = require('../package'); | ||
@@ -8,0 +7,0 @@ function listen() { |
@@ -11,3 +11,3 @@ import * as LSP from 'vscode-languageserver'; | ||
*/ | ||
static initialize(connection: LSP.Connection, {rootPath}: LSP.InitializeParams): Promise<BashServer>; | ||
static initialize(connection: LSP.Connection, { rootPath }: LSP.InitializeParams): Promise<BashServer>; | ||
private executables; | ||
@@ -27,10 +27,10 @@ private analyzer; | ||
capabilities(): LSP.ServerCapabilities; | ||
private getWordAtPoint(params); | ||
private onHover(pos); | ||
private onDefinition(pos); | ||
private onDocumentSymbol(params); | ||
private onDocumentHighlight(pos); | ||
private onReferences(params); | ||
private onCompletion(pos); | ||
private onCompletionResolve(item); | ||
private getWordAtPoint; | ||
private onHover; | ||
private onDefinition; | ||
private onDocumentSymbol; | ||
private onDocumentHighlight; | ||
private onReferences; | ||
private onCompletion; | ||
private onCompletionResolve; | ||
} |
@@ -11,4 +11,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const TurndownService = require("turndown"); | ||
const LSP = require("vscode-languageserver"); | ||
const TurndownService = require("turndown"); | ||
const analyser_1 = require("./analyser"); | ||
@@ -56,3 +56,3 @@ const Builtins = require("./builtins"); | ||
this.documents.onDidChangeContent(change => { | ||
const uri = change.document.uri; | ||
const { uri } = change.document; | ||
const diagnostics = this.analyzer.analyze(uri, change.document); | ||
@@ -108,3 +108,3 @@ if (config.getHighlightParsingError()) { | ||
if (response.status === 'error') { | ||
this.connection.console.log('getExplainshellDocumentation returned: ' + JSON.stringify(response, null, 4)); | ||
this.connection.console.log(`getExplainshellDocumentation returned: ${JSON.stringify(response, null, 4)}`); | ||
} | ||
@@ -120,8 +120,11 @@ else { | ||
} | ||
const getMarkdownHoverItem = (doc) => ({ | ||
// LSP.MarkupContent | ||
value: ['``` man', doc, '```'].join('\n'), | ||
// Passed as markdown for syntax highlighting | ||
kind: 'markdown', | ||
}); | ||
if (Builtins.isBuiltin(word)) { | ||
return Builtins.documentation(word).then(doc => ({ | ||
contents: { | ||
language: 'plaintext', | ||
value: doc, | ||
}, | ||
contents: getMarkdownHoverItem(doc), | ||
})); | ||
@@ -131,6 +134,3 @@ } | ||
return this.executables.documentation(word).then(doc => ({ | ||
contents: { | ||
language: 'plaintext', | ||
value: doc, | ||
}, | ||
contents: getMarkdownHoverItem(doc), | ||
})); | ||
@@ -184,11 +184,18 @@ } | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const { data: { name, type } } = item; | ||
const { data: { name, type }, } = item; | ||
const getMarkdownCompletionItem = (doc) => (Object.assign({}, item, { | ||
// LSP.MarkupContent | ||
documentation: { | ||
value: ['``` man', doc, '```'].join('\n'), | ||
// Passed as markdown for syntax highlighting | ||
kind: 'markdown', | ||
} })); | ||
try { | ||
if (type === 'executable') { | ||
const doc = yield this.executables.documentation(name); | ||
return Object.assign({}, item, { detail: doc }); | ||
return getMarkdownCompletionItem(doc); | ||
} | ||
else if (type === 'builtin') { | ||
const doc = yield Builtins.documentation(name); | ||
return Object.assign({}, item, { detail: doc }); | ||
return getMarkdownCompletionItem(doc); | ||
} | ||
@@ -195,0 +202,0 @@ else { |
@@ -1,4 +0,4 @@ | ||
export declare function flattenArray<T>(nestedArray: Array<Array<T>>): Array<T>; | ||
export declare function flattenArray<T>(nestedArray: T[][]): T[]; | ||
export declare function flattenObjectValues<T>(object: { | ||
[key: string]: Array<T>; | ||
}): Array<T>; | ||
[key: string]: T[]; | ||
}): T[]; |
/// <reference types="node" /> | ||
import * as Fs from 'fs'; | ||
export declare function getStats(path: string): Promise<Fs.Stats>; | ||
export declare function untildify(pathWithTilde: string): string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const Fs = require("fs"); | ||
const Os = require("os"); | ||
function getStats(path) { | ||
@@ -17,2 +18,10 @@ return new Promise((resolve, reject) => { | ||
exports.getStats = getStats; | ||
// from https://github.com/sindresorhus/untildify/blob/f85a087418aeaa2beb56fe2684fe3b64fc8c588d/index.js#L11 | ||
function untildify(pathWithTilde) { | ||
const homeDirectory = Os.homedir(); | ||
return homeDirectory | ||
? pathWithTilde.replace(/^~(?=$|\/|\\)/, homeDirectory) | ||
: pathWithTilde; | ||
} | ||
exports.untildify = untildify; | ||
//# sourceMappingURL=fs.js.map |
"use strict"; | ||
// tslint:disable:no-submodule-imports | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -4,0 +3,0 @@ const main_1 = require("vscode-languageserver/lib/main"); |
@@ -6,5 +6,5 @@ { | ||
"license": "MIT", | ||
"version": "1.6.1", | ||
"version": "1.7.0", | ||
"publisher": "mads-hartmann", | ||
"main": "out/server.js", | ||
"main": "./out/server.js", | ||
"typings": "./out/server.d.ts", | ||
@@ -34,3 +34,9 @@ "bin": { | ||
"prepublishOnly": "yarn run compile" | ||
}, | ||
"devDependencies": { | ||
"@types/glob": "^7.1.1", | ||
"@types/request-promise-native": "^1.0.17", | ||
"@types/turndown": "^5.0.0", | ||
"@types/urijs": "^1.19.4" | ||
} | ||
} |
import * as path from 'path' | ||
import Executables from '../executables' | ||
@@ -3,0 +4,0 @@ |
@@ -1,12 +0,9 @@ | ||
// tslint:disable:no-submodule-imports | ||
import * as fs from 'fs' | ||
import * as glob from 'glob' | ||
import * as Path from 'path' | ||
import * as request from 'request-promise-native' | ||
import * as URI from 'urijs' | ||
import * as LSP from 'vscode-languageserver' | ||
import * as Parser from 'web-tree-sitter' | ||
import * as LSP from 'vscode-languageserver' | ||
import { uniqueBasedOnHash } from './util/array' | ||
@@ -61,4 +58,4 @@ import { flattenArray, flattenObjectValues } from './util/flatten' | ||
if (fs.existsSync(absolute) && fs.lstatSync(absolute).isFile()) { | ||
const uri = 'file://' + absolute | ||
connection.console.log('Analyzing ' + uri) | ||
const uri = `file://${absolute}` | ||
connection.console.log(`Analyzing ${uri}`) | ||
analyzer.analyze( | ||
@@ -94,5 +91,7 @@ uri, | ||
// These keys are using underscores as that's the naming convention in tree-sitter. | ||
/* eslint-disable @typescript-eslint/camelcase */ | ||
environment_variable_assignment: LSP.SymbolKind.Variable, | ||
function_definition: LSP.SymbolKind.Function, | ||
variable_assignment: LSP.SymbolKind.Variable, | ||
/* eslint-enable @typescript-eslint/camelcase */ | ||
} | ||
@@ -142,2 +141,3 @@ | ||
// FIXME: type the response and unit test it | ||
const explainshellResponse = await request({ | ||
@@ -165,3 +165,3 @@ uri: URI(endpoint) | ||
const match = explainshellResponse.matches.find( | ||
helpItem => | ||
(helpItem: any) => | ||
helpItem.start <= offsetOfMousePointerInCommand && | ||
@@ -197,3 +197,3 @@ offsetOfMousePointerInCommand < helpItem.end, | ||
const locations = [] | ||
const locations: LSP.Location[] = [] | ||
@@ -234,3 +234,3 @@ TreeSitterUtil.forEach(tree.rootNode, n => { | ||
public findSymbolCompletions(uri: string): LSP.CompletionItem[] { | ||
const hashFunction = ({ name, kind }) => `${name}${kind}` | ||
const hashFunction = ({ name, kind }: LSP.SymbolInformation) => `${name}${kind}` | ||
@@ -266,3 +266,3 @@ return uniqueBasedOnHash(this.findSymbols(uri), hashFunction).map( | ||
const problems = [] | ||
const problems: LSP.Diagnostic[] = [] | ||
@@ -269,0 +269,0 @@ TreeSitterUtil.forEach(tree.rootNode, (n: Parser.SyntaxNode) => { |
@@ -33,3 +33,3 @@ import * as Fs from 'fs' | ||
*/ | ||
public list(): Array<string> { | ||
public list(): string[] { | ||
return Array.from(this.executables.values()) | ||
@@ -63,2 +63,3 @@ } | ||
function findExecutablesInPath(path: string): Promise<string[]> { | ||
path = FsUtil.untildify(path) | ||
return new Promise((resolve, _) => { | ||
@@ -65,0 +66,0 @@ Fs.lstat(path, (err, stat) => { |
@@ -7,3 +7,2 @@ 'use strict' | ||
// tslint:disable-next-line:no-var-requires | ||
const pkg = require('../package') | ||
@@ -19,18 +18,18 @@ | ||
connection.onInitialize((params: LSP.InitializeParams): Promise< | ||
LSP.InitializeResult | ||
> => { | ||
connection.console.log(`Initialized server v. ${pkg.version} for ${params.rootUri}`) | ||
connection.onInitialize( | ||
(params: LSP.InitializeParams): Promise<LSP.InitializeResult> => { | ||
connection.console.log(`Initialized server v. ${pkg.version} for ${params.rootUri}`) | ||
return BashServer.initialize(connection, params) | ||
.then(server => { | ||
server.register(connection) | ||
return server | ||
}) | ||
.then(server => ({ | ||
capabilities: server.capabilities(), | ||
})) | ||
}) | ||
return BashServer.initialize(connection, params) | ||
.then(server => { | ||
server.register(connection) | ||
return server | ||
}) | ||
.then(server => ({ | ||
capabilities: server.capabilities(), | ||
})) | ||
}, | ||
) | ||
connection.listen() | ||
} |
@@ -0,4 +1,4 @@ | ||
import * as TurndownService from 'turndown' | ||
import * as LSP from 'vscode-languageserver' | ||
import * as TurndownService from 'turndown' | ||
import Analyzer from './analyser' | ||
@@ -60,3 +60,3 @@ import * as Builtins from './builtins' | ||
this.documents.onDidChangeContent(change => { | ||
const uri = change.document.uri | ||
const { uri } = change.document | ||
const diagnostics = this.analyzer.analyze(uri, change.document) | ||
@@ -126,3 +126,3 @@ if (config.getHighlightParsingError()) { | ||
this.connection.console.log( | ||
'getExplainshellDocumentation returned: ' + JSON.stringify(response, null, 4), | ||
`getExplainshellDocumentation returned: ${JSON.stringify(response, null, 4)}`, | ||
) | ||
@@ -139,8 +139,12 @@ } else { | ||
const getMarkdownHoverItem = (doc: string) => ({ | ||
// LSP.MarkupContent | ||
value: ['``` man', doc, '```'].join('\n'), | ||
// Passed as markdown for syntax highlighting | ||
kind: 'markdown' as const, | ||
}) | ||
if (Builtins.isBuiltin(word)) { | ||
return Builtins.documentation(word).then(doc => ({ | ||
contents: { | ||
language: 'plaintext', | ||
value: doc, | ||
}, | ||
contents: getMarkdownHoverItem(doc), | ||
})) | ||
@@ -151,6 +155,3 @@ } | ||
return this.executables.documentation(word).then(doc => ({ | ||
contents: { | ||
language: 'plaintext', | ||
value: doc, | ||
}, | ||
contents: getMarkdownHoverItem(doc), | ||
})) | ||
@@ -220,16 +221,23 @@ } | ||
): Promise<LSP.CompletionItem> { | ||
const { data: { name, type } } = item | ||
const { | ||
data: { name, type }, | ||
} = item | ||
const getMarkdownCompletionItem = (doc: string) => ({ | ||
...item, | ||
// LSP.MarkupContent | ||
documentation: { | ||
value: ['``` man', doc, '```'].join('\n'), | ||
// Passed as markdown for syntax highlighting | ||
kind: 'markdown' as const, | ||
}, | ||
}) | ||
try { | ||
if (type === 'executable') { | ||
const doc = await this.executables.documentation(name) | ||
return { | ||
...item, | ||
detail: doc, | ||
} | ||
return getMarkdownCompletionItem(doc) | ||
} else if (type === 'builtin') { | ||
const doc = await Builtins.documentation(name) | ||
return { | ||
...item, | ||
detail: doc, | ||
} | ||
return getMarkdownCompletionItem(doc) | ||
} else { | ||
@@ -236,0 +244,0 @@ return item |
@@ -1,7 +0,7 @@ | ||
export function flattenArray<T>(nestedArray: Array<Array<T>>): Array<T> { | ||
export function flattenArray<T>(nestedArray: T[][]): T[] { | ||
return nestedArray.reduce((acc, array) => [...acc, ...array], []) | ||
} | ||
export function flattenObjectValues<T>(object: { [key: string]: Array<T> }): Array<T> { | ||
export function flattenObjectValues<T>(object: { [key: string]: T[] }): T[] { | ||
return flattenArray(Object.keys(object).map(objectKey => object[objectKey])) | ||
} |
import * as Fs from 'fs' | ||
import * as Os from 'os' | ||
@@ -14,1 +15,9 @@ export function getStats(path: string): Promise<Fs.Stats> { | ||
} | ||
// from https://github.com/sindresorhus/untildify/blob/f85a087418aeaa2beb56fe2684fe3b64fc8c588d/index.js#L11 | ||
export function untildify(pathWithTilde: string): string { | ||
const homeDirectory = Os.homedir() | ||
return homeDirectory | ||
? pathWithTilde.replace(/^~(?=$|\/|\\)/, homeDirectory) | ||
: pathWithTilde | ||
} |
@@ -1,3 +0,1 @@ | ||
// tslint:disable:no-submodule-imports | ||
import { Range } from 'vscode-languageserver/lib/main' | ||
@@ -4,0 +2,0 @@ import { SyntaxNode } from 'web-tree-sitter' |
@@ -6,6 +6,9 @@ { | ||
"lib": [ | ||
"dom", // Required by @types/turndown | ||
"es2016" | ||
], | ||
// TODO: enable: | ||
"strict": false, | ||
"noImplicitAny": false, | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
1079111
2167
4
64