diff --git a/extensions/css-language-features/server/src/pathCompletion.ts b/extensions/css-language-features/server/src/pathCompletion.ts index 76b93f3a628496791919c0dc78e93bf0297913c7..2f840184a14b260f94d925e2bfc9a314c15f8224 100644 --- a/extensions/css-language-features/server/src/pathCompletion.ts +++ b/extensions/css-language-features/server/src/pathCompletion.ts @@ -10,7 +10,7 @@ import URI from 'vscode-uri'; import { TextDocument, CompletionList, CompletionItemKind, CompletionItem, TextEdit, Range, Position } from 'vscode-languageserver-types'; import { WorkspaceFolder } from 'vscode-languageserver'; -import { ICompletionParticipant } from 'vscode-css-languageservice'; +import { ICompletionParticipant, URILiteralCompletionContext } from 'vscode-css-languageservice'; import { startsWith } from './utils/strings'; @@ -20,7 +20,7 @@ export function getPathCompletionParticipant( result: CompletionList ): ICompletionParticipant { return { - onURILiteralValue: (context: { uriValue: string, position: Position, range: Range; }) => { + onURILiteralValue: (context: URILiteralCompletionContext) => { if (!workspaceFolders || workspaceFolders.length === 0) { return; } @@ -91,7 +91,11 @@ export function providePathSuggestions(value: string, range: Range, activeDocFsP } const isDir = (p: string) => { - return fs.statSync(p).isDirectory(); + try { + return fs.statSync(p).isDirectory(); + } catch (e) { + return false; + } }; function resolveWorkspaceRoot(activeDoc: TextDocument, workspaceFolders: WorkspaceFolder[]): string | undefined { diff --git a/extensions/css-language-features/server/src/test/completion.test.ts b/extensions/css-language-features/server/src/test/completion.test.ts index 518a467cf4008142b65271713b0935607e4575ca..82f1af7026d2be9c36083b6941bf3557f184a586 100644 --- a/extensions/css-language-features/server/src/test/completion.test.ts +++ b/extensions/css-language-features/server/src/test/completion.test.ts @@ -77,5 +77,19 @@ suite('Completions', () => { { label: 'src/', resultText: `html { background-image: url('../src/')` } ] }, testUri); + + assertCompletions(`html { background-image: url('../src/a|')`, { + items: [ + { label: 'feature.js', resultText: `html { background-image: url('../src/feature.js')` }, + { label: 'data/', resultText: `html { background-image: url('../src/data/')` }, + { label: 'test.js', resultText: `html { background-image: url('../src/test.js')` } + ] + }, testUri); + + assertCompletions(`html { background-image: url('../src/data/f|.asar')`, { + items: [ + { label: 'foo.asar', resultText: `html { background-image: url('../src/data/foo.asar')` } + ] + }, testUri); }); }); \ No newline at end of file diff --git a/extensions/css-language-features/server/test/pathCompletionFixtures/src/data/foo.asar b/extensions/css-language-features/server/test/pathCompletionFixtures/src/data/foo.asar new file mode 100644 index 0000000000000000000000000000000000000000..adae63e647cb9188d7df4b63c9335b1c9811dbd1 --- /dev/null +++ b/extensions/css-language-features/server/test/pathCompletionFixtures/src/data/foo.asar @@ -0,0 +1,4 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ \ No newline at end of file diff --git a/extensions/html-language-features/server/src/modes/pathCompletion.ts b/extensions/html-language-features/server/src/modes/pathCompletion.ts index afb5089fbfd3da8cd31ef22fb48aabfda0816298..10e4649a0e30f277233a212ba82698341590fe52 100644 --- a/extensions/html-language-features/server/src/modes/pathCompletion.ts +++ b/extensions/html-language-features/server/src/modes/pathCompletion.ts @@ -82,7 +82,7 @@ function providePaths(valueBeforeCursor: string, activeDocFsPath: string, root?: try { return fs.readdirSync(parentDir).map(f => { - return fs.statSync(path.resolve(parentDir, f)).isDirectory() + return isDir(path.resolve(parentDir, f)) ? f + '/' : f; }); @@ -91,6 +91,14 @@ function providePaths(valueBeforeCursor: string, activeDocFsPath: string, root?: } } +function isDir(p: string) { + try { + return fs.statSync(p).isDirectory(); + } catch (e) { + return false; + } +} + function pathToSuggestion(p: string, valueBeforeCursor: string, fullValue: string, range: Range): CompletionItem { const isDir = p[p.length - 1] === '/';