fish-lsp
Version:
LSP implementation for fish/fish-shell
290 lines (289 loc) • 14.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.commandBin = void 0;
const commander_cli_subcommands_1 = require("./utils/commander-cli-subcommands");
const commander_1 = require("commander");
const get_lsp_completions_1 = require("./utils/get-lsp-completions");
const logger_1 = require("./logger");
const config_1 = require("./config");
const startup_1 = require("./utils/startup");
const health_check_1 = require("./utils/health-check");
const process_env_1 = require("./utils/process-env");
const createFishLspBin = () => {
const bin = new commander_1.Command('fish-lsp')
.description(`Description:\n${commander_cli_subcommands_1.FishLspHelp.description || 'fish-lsp command output'}`)
.helpOption('-h, --help', 'show the relevant help info. Use `--help-all` for comprehensive documentation of all commands and flags. Other `--help-*` flags are also available.')
.version(commander_cli_subcommands_1.PackageVersion, '-v, --version', 'output the version number')
.enablePositionalOptions(true)
.configureHelp({
showGlobalOptions: false,
commandUsage: (_) => commander_cli_subcommands_1.FishLspHelp.usage,
})
.showSuggestionAfterError(true)
.showHelpAfterError(true)
.addHelpText('after', commander_cli_subcommands_1.FishLspHelp.after);
return bin;
};
exports.commandBin = createFishLspBin();
exports.commandBin
.addOption(new commander_1.Option('--help-man', 'show special manpage output').hideHelp(true))
.addOption(new commander_1.Option('--help-all', 'show all help info').hideHelp(true))
.addOption(new commander_1.Option('--help-short', 'show mini help info').hideHelp(true))
.action(opt => {
if (opt.helpMan) {
const { path: _path, content } = (0, commander_cli_subcommands_1.FishLspManPage)();
logger_1.logger.logToStdout(content.join('\n').trim());
}
else if (opt.helpAll) {
const globalOpts = exports.commandBin.options.concat(new commander_1.Option('-h, --help', 'show help'));
const subCommands = exports.commandBin.commands.map((cmd) => {
return [
` ${cmd.name()} ${cmd.usage()}\t${cmd.summary()}`,
cmd.options.map(o => ` ${o.flags}\t\t${o.description}`).join('\n'),
''
].join('\n');
});
logger_1.logger.logToStdout(['NAME:',
'fish-lsp - an lsp for the fish shell language',
'',
'USAGE: ',
commander_cli_subcommands_1.FishLspHelp.beforeAll,
'',
'DESCRIPTION:',
' ' + exports.commandBin.description().split('\n').slice(1).join('\n').trim(),
'',
'OPTIONS:',
' ' + globalOpts.map(o => ' ' + o.flags + '\t' + o.description).join('\n').trim(),
'',
'SUBCOMMANDS:',
subCommands.join('\n'),
'',
'EXAMPLES:',
commander_cli_subcommands_1.FishLspHelp.after.split('\n').slice(2).join('\n'),
].join('\n').trim());
}
else if (opt.helpShort) {
logger_1.logger.logToStdout([
'Usage: fish-lsp ', exports.commandBin.usage().split('\n').slice(0, 1),
'',
exports.commandBin.description(),
].join('\n'));
}
return;
});
exports.commandBin.command('start')
.summary('start the lsp')
.description('start the language server for a connection to a client')
.option('--dump', 'stop lsp & show the startup options being read')
.option('--enable <string...>', 'enable the startup option')
.option('--disable <string...>', 'disable the startup option')
.option('--stdio', 'use stdin/stdout for communication (default)')
.option('--node-ipc', 'use node IPC for communication')
.option('--socket <port>', 'use TCP socket for communication')
.option('--memory-limit <mb>', 'set memory usage limit in MB')
.option('--max-files <number>', 'override the maximum number of files to analyze')
.addHelpText('afterAll', [
'',
'Strings for \'--enable/--disable\' switches:',
`${config_1.validHandlers.map((opt, index) => {
return index < config_1.validHandlers.length - 1 && index > 0 && index % 5 === 0 ? `${opt},\n` :
index < config_1.validHandlers.length - 1 ? `${opt},` : opt;
}).join(' ').split('\n').map(line => `\t${line.trim()}`).join('\n')}`,
'',
'Examples:',
'\t>_ fish-lsp start --disable hover # only disable the hover feature',
'\t>_ fish-lsp start --disable complete logging index hover --dump',
'\t>_ fish-lsp start --enable --disable logging complete codeAction',
].join('\n'))
.action(async (opts) => {
await (0, process_env_1.setupProcessEnvExecFile)();
(0, config_1.updateHandlers)(config_1.config.fish_lsp_enabled_handlers, true);
(0, config_1.updateHandlers)(config_1.config.fish_lsp_disabled_handlers, false);
if (opts.maxFiles && !isNaN(parseInt(opts.maxFiles))) {
config_1.config.fish_lsp_max_background_files = parseInt(opts.maxFiles);
}
if (opts.memoryLimit && !isNaN(parseInt(opts.memoryLimit))) {
const limitInMB = parseInt(opts.memoryLimit);
process.env.NODE_OPTIONS = `--max-old-space-size=${limitInMB}`;
}
const connectionType = (0, startup_1.createConnectionType)(opts);
const connectionOptions = {};
if (opts.socket) {
connectionOptions.port = parseInt(opts.socket);
}
const { enabled, disabled, dumpCmd } = (0, commander_cli_subcommands_1.accumulateStartupOptions)(exports.commandBin.args);
(0, config_1.updateHandlers)(enabled, true);
(0, config_1.updateHandlers)(disabled, false);
config_1.Config.fixPopups(enabled, disabled);
if (dumpCmd) {
logger_1.logger.logFallbackToStdout({ handlers: config_1.configHandlers });
logger_1.logger.logFallbackToStdout({ config: config_1.config });
process.exit(0);
}
(0, startup_1.startServer)(connectionType, connectionOptions);
});
exports.commandBin.command('info')
.summary('show info about the fish-lsp')
.description('the info about the `fish-lsp` executable')
.option('--bin', 'show the path of the fish-lsp executable')
.option('--repo', 'show the path of the entire fish-lsp repo')
.option('--build-time', 'show the path of the entire fish-lsp repo')
.option('--lsp-version', 'show the lsp version')
.option('--capabilities', 'show the lsp capabilities')
.option('--man-file', 'show the man file path')
.option('--logs-file', 'show the logs file path')
.option('--log-file', 'show the log file path')
.option('--more', 'show the build time of the fish-lsp executable')
.option('--time-startup', 'time the startup of the fish-lsp executable')
.option('--health-check', 'run diagnostics and report health status')
.option('--check-health', 'run diagnostics and report health status')
.action(async (args) => {
await (0, process_env_1.setupProcessEnvExecFile)();
const capabilities = (0, commander_cli_subcommands_1.BuildCapabilityString)()
.split('\n')
.map(line => ` ${line}`).join('\n');
if (args.timeStartup) {
await (0, startup_1.timeServerStartup)();
process.exit(0);
}
if (args.bin) {
logger_1.logger.logToStdout(commander_cli_subcommands_1.PathObj.execFile);
process.exit(0);
}
if (args.repo) {
logger_1.logger.logToStdout(commander_cli_subcommands_1.PathObj.repo);
process.exit(0);
}
if (args.healthCheck || args.checkHealth) {
await (0, health_check_1.performHealthCheck)();
process.exit(0);
}
if (args.buildTime) {
logger_1.logger.logToStdout(`Build Time: ${(0, commander_cli_subcommands_1.getBuildTimeString)()}`);
process.exit(0);
}
if (args.capabilities) {
logger_1.logger.logToStdout(`Capabilities:\n${capabilities}`);
process.exit(0);
}
if (args.lspVersion) {
logger_1.logger.logToStdout(`LSP Version: ${commander_cli_subcommands_1.PackageLspVersion}`);
process.exit(0);
}
if (args.manFile) {
logger_1.logger.logToStdout(commander_cli_subcommands_1.PathObj.manFile);
process.exit(0);
}
if (args.logsFile || args.logFile) {
logger_1.logger.logToStdout(config_1.config.fish_lsp_log_file);
process.exit(0);
}
logger_1.logger.logToStdout(`Executable Path: ${commander_cli_subcommands_1.PathObj.execFile}`);
logger_1.logger.logToStdout(`Build Location: ${commander_cli_subcommands_1.PathObj.repo}`);
logger_1.logger.logToStdout(`Build Version: ${commander_cli_subcommands_1.PackageVersion}`);
logger_1.logger.logToStdout(`Build Time: ${(0, commander_cli_subcommands_1.getBuildTimeString)()}`);
logger_1.logger.logToStdout(`Install Type: ${(0, commander_cli_subcommands_1.isPkgBinary)() ? 'standalone executable' : 'local build'}`);
logger_1.logger.logToStdout(`Node Version: ${process.version}`);
logger_1.logger.logToStdout(`LSP Version: ${commander_cli_subcommands_1.PackageLspVersion}`);
logger_1.logger.logToStdout(`Binary File: ${commander_cli_subcommands_1.PathObj.bin}`);
logger_1.logger.logToStdout(`Man File: ${commander_cli_subcommands_1.PathObj.manFile}`);
logger_1.logger.logToStdout(`Log File: ${config_1.config.fish_lsp_log_file}`);
logger_1.logger.logToStdout('_'.repeat(parseInt(process.env.COLUMNS || '80')));
logger_1.logger.logToStdout('CAPABILITIES:');
logger_1.logger.logToStdout(capabilities);
process.exit(0);
});
exports.commandBin.command('url')
.summary('show helpful url(s) related to the fish-lsp')
.description('show the related url to the fish-lsp')
.option('--repo, --git', 'show the github repo')
.option('--npm', 'show the npm package url')
.option('--homepage', 'show the homepage')
.option('--contributions', 'show the contributions url')
.option('--wiki', 'show the github wiki')
.option('--issues, --report', 'show the issues page')
.option('--discussions', 'show the discussions page')
.option('--clients-repo', 'show the clients configuration repo')
.option('--sources', 'show a list of helpful sources')
.action(args => {
const amount = Object.keys(args).length;
if (amount === 0)
logger_1.logger.logToStdout('https://fish-lsp.dev');
Object.keys(args).forEach(key => logger_1.logger.logToStdout(commander_cli_subcommands_1.SourcesDict[key]?.toString() || ''));
process.exit(0);
});
exports.commandBin.command('complete')
.summary('generate fish shell completions')
.description('the completions for the `fish-lsp` executable')
.option('--names', 'show the feature names of the completions')
.option('--names-with-summary', 'show names with their summary for a completions script')
.option('--toggles', 'show the feature names of the completions')
.option('--fish', 'show fish script')
.option('--features', 'show features')
.option('--env-variables', 'show env variables')
.option('--env-variable-names', 'show env variable names')
.description('copy completions output to fish-lsp completions file')
.action(async (args) => {
await (0, process_env_1.setupProcessEnvExecFile)();
if (args.names) {
exports.commandBin.commands.forEach(cmd => logger_1.logger.logToStdout(cmd.name()));
process.exit(0);
}
else if (args.namesWithSummary) {
exports.commandBin.commands.forEach(cmd => logger_1.logger.logToStdout(cmd.name() + '\t' + cmd.summary()));
process.exit(0);
}
else if (args.fish) {
logger_1.logger.logToStdout((0, get_lsp_completions_1.buildFishLspCompletions)(exports.commandBin));
process.exit(0);
}
else if (args.features || args.toggles) {
Object.keys(config_1.configHandlers).forEach((name) => logger_1.logger.logToStdout(name.toString()));
process.exit(0);
}
else if (args.envVariables) {
Object.entries(config_1.Config.envDocs).forEach(([key, value]) => {
logger_1.logger.logToStdout(`${key}\\t'${value}'`);
});
process.exit(0);
}
else if (args.envVariableNames) {
Object.keys(config_1.Config.envDocs).forEach((name) => logger_1.logger.logToStdout(name.toString()));
process.exit(0);
}
logger_1.logger.logToStdout((0, get_lsp_completions_1.buildFishLspCompletions)(exports.commandBin));
process.exit(0);
});
exports.commandBin.command('env')
.summary('generate environment variables for lsp configuration')
.description('generate fish-lsp env variables')
.option('-c, --create', 'build initial fish-lsp env variables')
.option('-s, --show', 'show the current fish-lsp env variables')
.option('--show-default', 'show the default fish-lsp env variables')
.option('--only <variables...>', 'only show specified variables (comma-separated)')
.option('--no-comments', 'skip comments in output')
.option('--no-global', 'use local env variables')
.option('--no-local', 'do not use local scope for variables')
.option('--no-export', 'don\'t export the variables')
.option('--confd', 'output for piping to conf.d')
.option('--names', 'show only the variable names')
.option('--joined', 'print the names in a single line')
.action(async (args) => {
await (0, process_env_1.setupProcessEnvExecFile)();
const outputType = commander_cli_subcommands_1.SubcommandEnv.getOutputType(args);
const opts = commander_cli_subcommands_1.SubcommandEnv.toEnvOutputOptions(args);
if (args.names) {
let result = '';
Object.keys(config_1.Config.envDocs).forEach((name) => {
if (args?.only && args.only.length > 0 && !args.only.includes(name))
return;
result += args.joined ? `${name} ` : `${name}\n`;
});
logger_1.logger.logToStdout(result.trim());
process.exit(0);
}
(0, config_1.handleEnvOutput)(outputType, logger_1.logger.logToStdout, opts);
process.exit(0);
});
exports.commandBin.parse();