fish-lsp
Version:
LSP implementation for fish/fish-shell
175 lines (174 loc) • 6.28 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.fishLspPromptIcon = exports.execAsync = void 0;
exports.execLineInBuffer = execLineInBuffer;
exports.buildOutput = buildOutput;
exports.buildExecuteNotificationResponse = buildExecuteNotificationResponse;
exports.execEntireBuffer = execEntireBuffer;
exports.sourceFishBuffer = sourceFishBuffer;
exports.FishThemeDump = FishThemeDump;
exports.showCurrentTheme = showCurrentTheme;
exports.executeThemeDump = executeThemeDump;
exports.useMessageKind = useMessageKind;
const child_process_1 = require("child_process");
const exec_1 = require("./utils/exec");
const util_1 = require("util");
const fs_1 = require("fs");
exports.execAsync = (0, util_1.promisify)(child_process_1.exec);
async function execLineInBuffer(line) {
const { stderr, stdout } = await (0, exports.execAsync)(`fish -c '${line}'; or true`);
if (stderr) {
return { message: buildOutput(line, 'stderr:', stderr), kind: 'error' };
}
if (stdout) {
return { message: buildOutput(line, 'stdout:', stdout), kind: 'info' };
}
return {
message: [
`${exports.fishLspPromptIcon} ${line}`,
'-'.repeat(50),
'EMPTY RESULT',
].join('\n'),
kind: 'info',
};
}
exports.fishLspPromptIcon = '><(((°>';
function buildOutput(line, outputMessage, output) {
const tokens = line.trim().split(' ');
let promptLine = `${exports.fishLspPromptIcon} `;
let currentLen = promptLine.length;
for (const token of tokens) {
if (1 + token.length + currentLen > 49) {
const newToken = `\\\n ${token} `;
promptLine += newToken;
currentLen = newToken.slice(newToken.indexOf('\n')).length;
}
else {
const newToken = token + ' ';
promptLine += newToken;
currentLen += newToken.length + 1;
}
}
return [
promptLine,
'-'.repeat(50),
`${outputMessage} ${output}`,
].join('\n');
}
function buildExecuteNotificationResponse(input, output) {
const outputType = output.stdout ? output.stdout : output.stderr;
const outputMessagePrefix = output.stdout ? 'stdout:' : 'stderr:';
const kind = output.stdout ? 'info' : 'error';
return {
message: buildOutput(input, outputMessagePrefix, outputType),
kind,
};
}
async function execEntireBuffer(bufferName) {
const { stdout, stderr } = await (0, exports.execAsync)(`fish ${bufferName}`);
const statusOutput = (await (0, exports.execAsync)(`fish -c 'fish ${bufferName} 1> /dev/null; echo "\\$status: $status"'`)).stdout;
const headerOutput = [
`${exports.fishLspPromptIcon} executing file:`,
`${' '.repeat(exports.fishLspPromptIcon.length)} ${bufferName}`,
].join('\n');
const longestLineLen = findLongestLine(headerOutput, stdout, stderr, '-'.repeat(50)).length;
let output = '';
if (stdout)
output += `${stdout}`;
if (stdout && stderr)
output += `\nerror:\n${stderr}`;
else if (!stdout && stderr)
output += `error:\n${stderr}`;
let messageType = 'info';
if (stderr)
messageType = 'error';
if (statusOutput)
output += `${'-'.repeat(longestLineLen)}\n${statusOutput}`;
return {
message: [
headerOutput,
'-'.repeat(longestLineLen),
output,
].join('\n'),
kind: messageType,
};
}
async function sourceFishBuffer(bufferName) {
const { stdout, stderr } = await (0, exports.execAsync)(`fish -c 'source ${bufferName}'`);
const statusOutput = (await (0, exports.execAsync)(`fish -c 'source ${bufferName} 1> /dev/null; echo "\\$status: $status"'`)).stdout;
const message = [
`${exports.fishLspPromptIcon} sourcing file:`,
`${' '.repeat(exports.fishLspPromptIcon.length)} ${bufferName}`,
].join('\n');
const longestLineLen = findLongestLine(message, stdout, stderr, statusOutput, '-'.repeat(50)).length;
const outputArr = [];
if (statusOutput)
outputArr.push(statusOutput);
if (stdout)
outputArr.push(stdout);
if (stderr)
outputArr.push(stderr);
const output = outputArr.join('-'.repeat(50) + '\n');
return [
message,
'-'.repeat(longestLineLen),
output,
].join('\n');
}
async function FishThemeDump() {
return (await (0, exec_1.execAsyncFish)('fish_config theme dump; or true')).stdout.split('\n');
}
async function showCurrentTheme(buffName) {
const output = (await (0, exec_1.execAsyncFish)('fish_config theme demo; or true')).stdout.split('\n');
for (const line of output) {
(0, fs_1.appendFileSync)(buffName, `${line}\n`, 'utf8');
}
return {
message: `${exports.fishLspPromptIcon} appended theme variables to end of file`,
kind: 'info',
};
}
const defaultThemeOptions = {
asVariables: false,
};
async function executeThemeDump(buffName, options = defaultThemeOptions) {
const output = (await (0, exec_1.execAsyncFish)('fish_config theme dump; or true')).stdout.split('\n');
if (options.asVariables) {
(0, fs_1.appendFileSync)(buffName, '# created by fish-lsp');
}
for (const line of output) {
if (options.asVariables) {
(0, fs_1.appendFileSync)(buffName, `set -gx ${line}\n`, 'utf8');
}
else {
(0, fs_1.appendFileSync)(buffName, `${line}\n`, 'utf8');
}
}
return {
message: `${exports.fishLspPromptIcon} appended theme variables to end of file`,
kind: 'info',
};
}
function findLongestLine(...inputs) {
const input = inputs.join('\n');
const lines = input.split('\n');
let longestLine = '';
for (const line of lines) {
if (line.length > longestLine.length) {
longestLine = line;
}
}
return longestLine;
}
function useMessageKind(connection, result) {
switch (result.kind) {
case 'info':
connection.window.showInformationMessage(result.message);
return;
case 'error':
connection.window.showErrorMessage(result.message);
return;
default:
return;
}
}