fish-lsp
Version:
LSP implementation for fish/fish-shell
240 lines (239 loc) • 9.13 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AsyncFileHelper = exports.SyncFileHelper = void 0;
const fs_1 = require("fs");
const vscode_languageserver_1 = require("vscode-languageserver");
const document_1 = require("../document");
const translation_1 = require("./translation");
const path_1 = require("path");
const env_manager_1 = require("./env-manager");
const promises = __importStar(require("fs/promises"));
const logger_1 = require("../logger");
class SyncFileHelper {
static open(filePath, flags) {
const expandedFilePath = this.expandEnvVars(filePath);
return (0, fs_1.openSync)(expandedFilePath, flags);
}
static close(fd) {
(0, fs_1.closeSync)(fd);
}
static read(filePath, encoding = 'utf8') {
try {
const expandedFilePath = this.expandEnvVars(filePath);
if (this.isDirectory(expandedFilePath)) {
return '';
}
return (0, fs_1.readFileSync)(expandedFilePath, { encoding });
}
catch (error) {
logger_1.logger.error(`Error reading file: ${filePath}`, error);
return '';
}
}
static loadDocumentSync(filePath) {
try {
const expandedFilePath = this.expandEnvVars(filePath);
if (!this.exists(expandedFilePath)) {
return undefined;
}
const stats = (0, fs_1.statSync)(expandedFilePath);
if (stats.isDirectory()) {
return undefined;
}
const content = (0, fs_1.readFileSync)(expandedFilePath, { encoding: 'utf8' });
const uri = (0, translation_1.pathToUri)(expandedFilePath.toString());
const doc = vscode_languageserver_1.TextDocumentItem.create(uri, 'fish', 0, content);
return new document_1.LspDocument(doc);
}
catch (error) {
return undefined;
}
}
static write(filePath, data, encoding = 'utf8') {
const expandedFilePath = this.expandEnvVars(filePath);
(0, fs_1.writeFileSync)(expandedFilePath, data, { encoding });
}
static append(filePath, data, encoding = 'utf8') {
const expandedFilePath = this.expandEnvVars(filePath);
(0, fs_1.appendFileSync)(expandedFilePath, data, { encoding });
}
static expandEnvVars(filePath) {
let filePathString = filePath.toString();
filePathString = filePathString.replace(/^~/, process.env.HOME);
filePathString = filePathString.replace(/\$([a-zA-Z0-9_]+)/g, (_, envVarName) => {
return env_manager_1.env.get(envVarName) || '';
});
return filePathString;
}
static exists(filePath) {
const expandedFilePath = this.expandEnvVars(filePath);
return (0, fs_1.existsSync)(expandedFilePath);
}
static delete(filePath) {
(0, fs_1.unlinkSync)(filePath);
}
static create(filePath) {
const expandedFilePath = this.expandEnvVars(filePath);
if (this.isDirectory(expandedFilePath)) {
return this.getPathTokens(filePath);
}
else if (!this.exists(expandedFilePath)) {
this.write(expandedFilePath, '');
}
return this.getPathTokens(expandedFilePath);
}
static getPathTokens(filePath) {
const expandedFilePath = this.expandEnvVars(filePath);
return {
path: expandedFilePath,
filename: (0, path_1.basename)(expandedFilePath, (0, path_1.extname)(expandedFilePath)),
extension: (0, path_1.extname)(expandedFilePath).substring(1),
directory: (0, path_1.dirname)(expandedFilePath),
exists: this.exists(expandedFilePath),
uri: (0, translation_1.pathToUri)(expandedFilePath),
};
}
static convertTextToFishFunction(filePath, data, _encoding = 'utf8') {
const expandedFilePath = this.expandEnvVars(filePath);
const { filename, path, extension, exists } = this.getPathTokens(expandedFilePath);
const content = [
'',
`function ${filename}`,
data.split('\n').map(line => '\t' + line).join('\n'),
'end',
].join('\n');
if (exists) {
this.append(path, content, 'utf8');
return this.toLspDocument(path, extension);
}
this.write(path, content);
return this.toLspDocument(path, extension);
}
static toTextDocumentItem(filePath, languageId, version) {
const expandedFilePath = this.expandEnvVars(filePath);
const content = this.read(expandedFilePath);
const uri = (0, translation_1.pathToUri)(expandedFilePath.toString());
return vscode_languageserver_1.TextDocumentItem.create(uri, languageId, version, content);
}
static toLspDocument(filePath, languageId = 'fish', version = 1) {
const expandedFilePath = this.expandEnvVars(filePath);
let content = this.read(expandedFilePath);
if (!content) {
content = '';
}
const doc = this.toTextDocumentItem(expandedFilePath, languageId, version);
return new document_1.LspDocument(doc);
}
static isDirectory(filePath) {
const expandedFilePath = this.expandEnvVars(filePath);
try {
const fileStat = (0, fs_1.statSync)(expandedFilePath);
return fileStat.isDirectory();
}
catch (_) {
return false;
}
}
static isFile(filePath) {
const expandedFilePath = this.expandEnvVars(filePath);
try {
const fileStat = (0, fs_1.statSync)(expandedFilePath);
return fileStat.isFile();
}
catch (_) {
return false;
}
}
static isWriteableDirectory(workspacePath) {
const expandedPath = this.expandEnvVars(workspacePath);
if (!this.isDirectory(expandedPath)) {
return false;
}
return this.isWriteablePath(expandedPath);
}
static isWriteableFile(filePath) {
const expandedFilePath = this.expandEnvVars(filePath);
if (!this.isFile(expandedFilePath)) {
return false;
}
return this.isWriteablePath(expandedFilePath);
}
static isWriteable(filePath) {
const expandedFilePath = this.expandEnvVars(filePath);
return this.isWriteablePath(expandedFilePath);
}
static isWriteablePath(path) {
try {
(0, fs_1.accessSync)(path, fs_1.constants.W_OK);
return true;
}
catch (error) {
return false;
}
}
}
exports.SyncFileHelper = SyncFileHelper;
var AsyncFileHelper;
(function (AsyncFileHelper) {
async function isReadable(filePath) {
const expandedFilePath = SyncFileHelper.expandEnvVars(filePath);
try {
await promises.access(expandedFilePath, promises.constants.R_OK);
return true;
}
catch {
return false;
}
}
AsyncFileHelper.isReadable = isReadable;
async function isDir(filePath) {
const expandedFilePath = SyncFileHelper.expandEnvVars(filePath);
try {
const fileStat = await promises.stat(expandedFilePath);
return fileStat.isDirectory();
}
catch {
return false;
}
}
AsyncFileHelper.isDir = isDir;
async function isFile(filePath) {
const expandedFilePath = SyncFileHelper.expandEnvVars(filePath);
try {
const fileStat = await promises.stat(expandedFilePath);
return fileStat.isFile();
}
catch {
return false;
}
}
AsyncFileHelper.isFile = isFile;
async function readFile(filePath, encoding = 'utf8') {
const expandedFilePath = SyncFileHelper.expandEnvVars(filePath);
return promises.readFile(expandedFilePath, { encoding });
}
AsyncFileHelper.readFile = readFile;
})(AsyncFileHelper || (exports.AsyncFileHelper = AsyncFileHelper = {}));