Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@elastic/ctags-langserver

Package Overview
Dependencies
Maintainers
62
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@elastic/ctags-langserver - npm Package Compare versions

Comparing version 0.1.9 to 0.1.10

4

lib/lsp-server.d.ts

@@ -18,3 +18,3 @@ import { InitializeParams, InitializeResult, DidChangeWorkspaceFoldersParams, DocumentSymbolParams, TextDocumentPositionParams, Hover, Location, ReferenceParams, DocumentSymbol } from 'vscode-languageserver-protocol';

initialize(params: InitializeParams): Promise<InitializeResult>;
didChangeWorkspaceFolders(params: DidChangeWorkspaceFoldersParams): void;
didChangeWorkspaceFolders(params: DidChangeWorkspaceFoldersParams): Promise<void>;
documentSymbol(params: DocumentSymbolParams): Promise<DocumentSymbol[]>;

@@ -30,3 +30,5 @@ full(params: FullParams): Promise<Full>;

private runCtagsOnSingleFile;
private addSwiftSupport;
private addKotlinSupport;
protected findCtagsPath(): string;
}

@@ -41,2 +41,3 @@ "use strict";

'Iniconf',
'Kotlin',
'Lua',

@@ -55,2 +56,3 @@ 'JSON',

'SQL',
'Swift',
'Tcl',

@@ -74,4 +76,9 @@ 'TypeScript',

const rootPath = url_1.fileURLToPath(params.rootUri);
this.runCtags(rootPath);
this.rootPaths.push(rootPath);
yield this.runCtags(rootPath);
if (!fs_1.existsSync(path.resolve(rootPath, this.tagFileName))) {
this.logger.error(`Fail to initialize ${params.rootUri}`);
}
else {
this.rootPaths.push(rootPath);
}
this.initializeResult = {

@@ -90,14 +97,21 @@ capabilities: {

didChangeWorkspaceFolders(params) {
const added = params.event.added;
const removed = params.event.removed;
added.forEach(add => {
const rootPath = url_1.fileURLToPath(add.uri);
this.runCtags(rootPath);
this.rootPaths.push(rootPath);
});
removed.forEach(remove => {
const index = this.rootPaths.indexOf(url_1.fileURLToPath(remove.uri));
if (index !== -1) {
this.rootPaths.splice(index, 1);
return __awaiter(this, void 0, void 0, function* () {
const added = params.event.added;
const removed = params.event.removed;
for (const add of added) {
const rootPath = url_1.fileURLToPath(add.uri);
yield this.runCtags(rootPath);
if (!fs_1.existsSync(path.resolve(rootPath, this.tagFileName))) {
this.logger.error(`Fail to initialize ${add.uri}`);
}
else {
this.rootPaths.push(rootPath);
}
}
removed.forEach(remove => {
const index = this.rootPaths.indexOf(url_1.fileURLToPath(remove.uri));
if (index !== -1) {
this.rootPaths.splice(index, 1);
}
});
});

@@ -244,87 +258,93 @@ }

const relativePath = path.relative(rootPath, filePath);
this.runCtagsOnSingleFile(rootPath, relativePath);
const stream = ctags.createReadStream(path.resolve(rootPath, this.tmpTagName));
return new Promise(resolve => {
let results = [];
// @ts-ignore
stream.on('data', (tags) => {
yield this.runCtagsOnSingleFile(rootPath, relativePath);
if (!fs_1.existsSync(path.resolve(rootPath, this.tmpTagName))) {
this.logger.error(`Fail to generate tags for ${unitURI}`);
return [];
}
else {
const stream = ctags.createReadStream(path.resolve(rootPath, this.tmpTagName));
return new Promise(resolve => {
let results = [];
// @ts-ignore
for (let def of tags) {
let symbolInformation = vscode_languageserver_protocol_1.SymbolInformation.create(def.name, vscode_languageserver_protocol_1.SymbolKind.Method, vscode_languageserver_protocol_1.Range.create(vscode_languageserver_protocol_1.Position.create(def.lineNumber - 1, 0), vscode_languageserver_protocol_1.Position.create(def.lineNumber - 1, 0)), unitURI, relativePath);
if (def.fields !== undefined) {
if (def.fields.struct) {
symbolInformation.containerName = def.fields.struct;
stream.on('data', (tags) => {
// @ts-ignore
for (let def of tags) {
let symbolInformation = vscode_languageserver_protocol_1.SymbolInformation.create(def.name, vscode_languageserver_protocol_1.SymbolKind.Method, vscode_languageserver_protocol_1.Range.create(vscode_languageserver_protocol_1.Position.create(def.lineNumber - 1, 0), vscode_languageserver_protocol_1.Position.create(def.lineNumber - 1, 0)), unitURI, relativePath);
if (def.fields !== undefined) {
if (def.fields.struct) {
symbolInformation.containerName = def.fields.struct;
}
else if (def.fields.class) {
symbolInformation.containerName = def.fields.class;
}
else if (def.fields.interface) {
symbolInformation.containerName = def.fields.interface;
}
else if (def.fields.function) {
symbolInformation.containerName = def.fields.function;
}
else if (def.fields.enum) {
symbolInformation.containerName = def.fields.enum;
}
else if (def.fields.namespace) {
symbolInformation.containerName = def.fields.namespace;
}
else if (def.fields.module) {
symbolInformation.containerName = def.fields.module;
}
}
else if (def.fields.class) {
symbolInformation.containerName = def.fields.class;
switch (def.kind) {
case 'namespace':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Namespace;
break;
case 'package':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Package;
break;
case 'module':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Module;
break;
case 'variable':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Variable;
break;
case 'function':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Function;
break;
case 'class':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Class;
break;
case 'field':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Field;
break;
case 'method':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Method;
break;
case 'struct':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Struct;
break;
case 'enum':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Enum;
break;
case 'enumerator':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.EnumMember;
break;
case 'member':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Field;
break;
case 'typedef':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Interface;
break;
case 'macro':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Constant;
break;
default:
break;
}
else if (def.fields.interface) {
symbolInformation.containerName = def.fields.interface;
}
else if (def.fields.function) {
symbolInformation.containerName = def.fields.function;
}
else if (def.fields.enum) {
symbolInformation.containerName = def.fields.enum;
}
else if (def.fields.namespace) {
symbolInformation.containerName = def.fields.namespace;
}
else if (def.fields.module) {
symbolInformation.containerName = def.fields.module;
}
results.push(symbolInformation);
}
switch (def.kind) {
case 'namespace':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Namespace;
break;
case 'package':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Package;
break;
case 'module':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Module;
break;
case 'variable':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Variable;
break;
case 'function':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Function;
break;
case 'class':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Class;
break;
case 'field':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Field;
break;
case 'method':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Method;
break;
case 'struct':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Struct;
break;
case 'enum':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Enum;
break;
case 'enumerator':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.EnumMember;
break;
case 'member':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Field;
break;
case 'typedef':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Interface;
break;
case 'macro':
symbolInformation.kind = vscode_languageserver_protocol_1.SymbolKind.Constant;
break;
default:
break;
}
results.push(symbolInformation);
}
});
stream.on('end', () => {
resolve(results);
});
});
stream.on('end', () => {
resolve(results);
});
});
}
});

@@ -352,38 +372,55 @@ }

runCtags(rootPath) {
const ctagsPath = this.findCtagsPath();
const excludeCommands = utils_1.getGitIgnored(rootPath).map(pattern => `--exclude=${pattern}`).join(' ');
try {
child_process_1.execSync(`${ctagsPath} --fields=-anf+iKnS --languages=${CTAGS_SUPPORT_LANGS.join(',')} ${excludeCommands} -R`, { cwd: rootPath, stdio: 'pipe' });
}
catch (err) {
this.logger.error(`Fail to run ctags command with exit code ${err.status}`);
this.logger.error(`${err.stderr}`);
}
try {
if (!fs_1.existsSync(path.resolve(rootPath, this.tagFileName))) {
this.logger.error(`Cannot find tag file in ${path.resolve(rootPath, this.tagFileName)}`);
}
}
catch (err) {
this.logger.error(err);
}
return __awaiter(this, void 0, void 0, function* () {
const params = [
'--links=no',
'--fields=-anf+iKnS',
`--languages=${CTAGS_SUPPORT_LANGS.join(',')}`,
'-R',
];
this.addKotlinSupport(params);
this.addSwiftSupport(params);
const p = child_process_1.spawn(this.findCtagsPath(), params, { cwd: rootPath, stdio: 'pipe' });
p.stderr.on('data', data => {
this.logger.error(data.toString());
});
return new Promise((resolve) => {
p.on('exit', () => resolve());
});
});
}
runCtagsOnSingleFile(rootPath, filePath) {
const ctagsPath = this.findCtagsPath();
try {
child_process_1.execSync(`${ctagsPath} --fields=-anf+iKnS -f ${this.tmpTagName} ${filePath}`, { cwd: rootPath, stdio: 'pipe' });
const tmpTagsFile = path.resolve(rootPath, this.tmpTagName);
if (fs_1.existsSync(tmpTagsFile)) {
fs_1.unlinkSync(tmpTagsFile);
}
catch (err) {
this.logger.error(`Fail to run ctags command with exit code ${err.status}`);
this.logger.error(`${err.stderr}`);
}
try {
if (!fs_1.existsSync(path.resolve(rootPath, this.tmpTagName))) {
this.logger.error(`Cannot find tag file in ${path.resolve(rootPath, this.tmpTagName)}`);
}
}
catch (err) {
this.logger.error(err);
}
const params = [
'--links=no',
'--fields=-anf+iKnS',
'-f',
this.tmpTagName,
filePath,
];
const p = child_process_1.spawn(this.findCtagsPath(), params, { cwd: rootPath, stdio: 'pipe' });
p.stderr.on('data', data => {
this.logger.error(data.toString());
});
return new Promise((resolve) => {
p.on('exit', () => resolve());
});
}
// regex borrowed from https://github.com/oracle/opengrok/blob/master/opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Ctags.java
addSwiftSupport(command) {
command.unshift("--langdef=Swift", "--langmap=Swift:+.swift", "--regex-Swift=/enum[[:space:]]+([^\\{\\}]+).*$/\\1/n,enum,enums/", "--regex-Swift=/typealias[[:space:]]+([^:=]+).*$/\\1/t,typealias,typealiases/", "--regex-Swift=/struct[[:space:]]+([^:\\{]+).*$/\\1/s,struct,structs/", "--regex-Swift=/class[[:space:]]+([^:\\{]+).*$/\\1/c,class,classes/", "--regex-Swift=/func[[:space:]]+([^\\(\\)]+)\\([^\\(\\)]*\\)/\\1/f,function,functions/", "--regex-Swift=/(var|let)[[:space:]]+([^:=]+).*$/\\2/v,variable,variables/", "--regex-Swift=/^[[:space:]]*extension[[:space:]]+([^:\\{]+).*$/\\1/e,extension,extensions/");
}
addKotlinSupport(command) {
command.unshift("--langdef=Kotlin", "--langmap=Kotlin:+.kt", "--langmap=Kotlin:+.kts",
// tslint:disable-next-line: max-line-length
"--regex-Kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy)[[:space:]]*)*(private[^ ]*|protected)?[[:space:]]*class[[:space:]]+([[:alnum:]_:]+)/\\4/c,classes/",
// tslint:disable-next-line: max-line-length
"--regex-Kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy)[[:space:]]*)*(private[^ ]*|protected)?[[:space:]]*object[[:space:]]+([[:alnum:]_:]+)/\\4/o,objects/",
// tslint:disable-next-line: max-line-length
"--regex-Kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy)[[:space:]]*)*(private[^ ]*|protected)?[[:space:]]*((abstract|final|sealed|implicit|lazy)[[:space:]]*)*data class[[:space:]]+([[:alnum:]_:]+)/\\6/d,data classes/",
// tslint:disable-next-line: max-line-length
"--regex-Kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy)[[:space:]]*)*(private[^ ]*|protected)?[[:space:]]*interface[[:space:]]+([[:alnum:]_:]+)/\\4/i,interfaces/", "--regex-Kotlin=/^[[:space:]]*type[[:space:]]+([[:alnum:]_:]+)/\\1/T,types/", "--regex-Kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy|private[^ ]*(\\[[a-z]*\\])*|protected)[[:space:]]*)*fun[[:space:]]+([[:alnum:]_:]+)/\\4/m,methods/", "--regex-Kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy|private[^ ]*|protected)[[:space:]]*)*val[[:space:]]+([[:alnum:]_:]+)/\\3/C,constants/", "--regex-Kotlin=/^[[:space:]]*((abstract|final|sealed|implicit|lazy|private[^ ]*|protected)[[:space:]]*)*var[[:space:]]+([[:alnum:]_:]+)/\\3/v,variables/", "--regex-Kotlin=/^[[:space:]]*package[[:space:]]+([[:alnum:]_.:]+)/\\1/p,packages/", "--regex-Kotlin=/^[[:space:]]*import[[:space:]]+([[:alnum:]_.:]+)/\\1/I,imports/");
}
findCtagsPath() {

@@ -390,0 +427,0 @@ if (this.options.ctagsPath) {

@@ -55,7 +55,7 @@ "use strict";

}));
test('test didChangeWorkspaceFolders', () => {
test('test didChangeWorkspaceFolders', () => __awaiter(this, void 0, void 0, function* () {
const addedRootPath = fs.mkdtempSync(path.resolve(os.tmpdir(), 'ctags-langserver'));
const addedSourceFilePath = path.resolve(addedRootPath, 'test.c');
fs.writeFileSync(addedSourceFilePath, content);
lspServer.didChangeWorkspaceFolders({
yield lspServer.didChangeWorkspaceFolders({
event: {

@@ -72,3 +72,3 @@ added: [

expect(fs.existsSync(path.resolve(addedRootPath, 'tags'))).toBe(true);
});
}));
test('test documentSymbol', () => __awaiter(this, void 0, void 0, function* () {

@@ -75,0 +75,0 @@ const symbols = yield lspServer.documentSymbol({

{
"name": "@elastic/ctags-langserver",
"version": "0.1.9",
"version": "0.1.10",
"description": "An all-languages language server built on top of ctags",

@@ -5,0 +5,0 @@ "author": "Elastic",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc