Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/emmet/src/locateFile.ts
4772 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
// Based on @sergeche's work on the emmet plugin for atom
7
// TODO: Move to https://github.com/emmetio/file-utils
8
9
10
11
import * as path from 'path';
12
import * as fs from 'fs';
13
14
const reAbsolutePosix = /^\/+/;
15
const reAbsoluteWin32 = /^\\+/;
16
const reAbsolute = path.sep === '/' ? reAbsolutePosix : reAbsoluteWin32;
17
18
/**
19
* Locates given `filePath` on user's file system and returns absolute path to it.
20
* This method expects either URL, or relative/absolute path to resource
21
* @param basePath Base path to use if filePath is not absoulte
22
* @param filePath File to locate.
23
*/
24
export function locateFile(base: string, filePath: string): Promise<string> {
25
if (/^\w+:/.test(filePath)) {
26
// path with protocol, already absolute
27
return Promise.resolve(filePath);
28
}
29
30
filePath = path.normalize(filePath);
31
32
return reAbsolute.test(filePath)
33
? resolveAbsolute(base, filePath)
34
: resolveRelative(base, filePath);
35
}
36
37
/**
38
* Resolves relative file path
39
*/
40
function resolveRelative(basePath: string, filePath: string): Promise<string> {
41
return tryFile(path.resolve(basePath, filePath));
42
}
43
44
/**
45
* Resolves absolute file path agaist given editor: tries to find file in every
46
* parent of editor's file
47
*/
48
function resolveAbsolute(basePath: string, filePath: string): Promise<string> {
49
return new Promise((resolve, reject) => {
50
filePath = filePath.replace(reAbsolute, '');
51
52
const next = (ctx: string) => {
53
tryFile(path.resolve(ctx, filePath))
54
.then(resolve, () => {
55
const dir = path.dirname(ctx);
56
if (!dir || dir === ctx) {
57
return reject(`Unable to locate absolute file ${filePath}`);
58
}
59
60
next(dir);
61
});
62
};
63
64
next(basePath);
65
});
66
}
67
68
/**
69
* Check if given file exists and it's a file, not directory
70
*/
71
function tryFile(file: string): Promise<string> {
72
return new Promise((resolve, reject) => {
73
fs.stat(file, (err, stat) => {
74
if (err) {
75
return reject(err);
76
}
77
78
if (!stat.isFile()) {
79
return reject(new Error(`${file} is not a file`));
80
}
81
82
resolve(file);
83
});
84
});
85
}
86
87