Merge commit 'be3e8236086165e5e45a5a10783823874b3f3ebd' as 'lib/vscode'
This commit is contained in:
85
lib/vscode/extensions/emmet/src/locateFile.ts
Normal file
85
lib/vscode/extensions/emmet/src/locateFile.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
// Based on @sergeche's work on the emmet plugin for atom
|
||||
// TODO: Move to https://github.com/emmetio/file-utils
|
||||
|
||||
|
||||
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
|
||||
const reAbsolutePosix = /^\/+/;
|
||||
const reAbsoluteWin32 = /^\\+/;
|
||||
const reAbsolute = path.sep === '/' ? reAbsolutePosix : reAbsoluteWin32;
|
||||
|
||||
/**
|
||||
* Locates given `filePath` on user’s file system and returns absolute path to it.
|
||||
* This method expects either URL, or relative/absolute path to resource
|
||||
* @param basePath Base path to use if filePath is not absoulte
|
||||
* @param filePath File to locate.
|
||||
*/
|
||||
export function locateFile(base: string, filePath: string): Promise<string> {
|
||||
if (/^\w+:/.test(filePath)) {
|
||||
// path with protocol, already absolute
|
||||
return Promise.resolve(filePath);
|
||||
}
|
||||
|
||||
filePath = path.normalize(filePath);
|
||||
|
||||
return reAbsolute.test(filePath)
|
||||
? resolveAbsolute(base, filePath)
|
||||
: resolveRelative(base, filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves relative file path
|
||||
*/
|
||||
function resolveRelative(basePath: string, filePath: string): Promise<string> {
|
||||
return tryFile(path.resolve(basePath, filePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves absolute file path agaist given editor: tries to find file in every
|
||||
* parent of editor’s file
|
||||
*/
|
||||
function resolveAbsolute(basePath: string, filePath: string): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
filePath = filePath.replace(reAbsolute, '');
|
||||
|
||||
const next = (ctx: string) => {
|
||||
tryFile(path.resolve(ctx, filePath))
|
||||
.then(resolve, () => {
|
||||
const dir = path.dirname(ctx);
|
||||
if (!dir || dir === ctx) {
|
||||
return reject(`Unable to locate absolute file ${filePath}`);
|
||||
}
|
||||
|
||||
next(dir);
|
||||
});
|
||||
};
|
||||
|
||||
next(basePath);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if given file exists and it’s a file, not directory
|
||||
*/
|
||||
function tryFile(file: string): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.stat(file, (err, stat) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
if (!stat.isFile()) {
|
||||
return reject(new Error(`${file} is not a file`));
|
||||
}
|
||||
|
||||
resolve(file);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user