Skip to content

Commit

Permalink
feat: support file system for web
Browse files Browse the repository at this point in the history
close #612
  • Loading branch information
johnsoncodehk committed Sep 3, 2022
1 parent 20d713b commit c322297
Show file tree
Hide file tree
Showing 57 changed files with 2,394 additions and 435 deletions.
5 changes: 3 additions & 2 deletions extensions/vscode-alpine-language-features/src/common.ts
Expand Up @@ -6,6 +6,7 @@ import * as tsVersion from '../../vscode-vue-language-features/out/features/tsVe
import * as virtualFiles from '../../vscode-vue-language-features/out/features/virtualFiles';
import * as tsconfig from '../../vscode-vue-language-features/out/features/tsconfig';
import * as fileReferences from '../../vscode-vue-language-features/out/features/fileReferences';
import { ServerInitializationOptions } from '@volar/vue-language-server';

let apiClient: lsp.BaseLanguageClient;
let docClient: lsp.BaseLanguageClient | undefined;
Expand All @@ -15,7 +16,7 @@ type CreateLanguageClient = (
id: string,
name: string,
documentSelector: lsp.DocumentSelector,
initOptions: shared.ServerInitializationOptions,
initOptions: ServerInitializationOptions,
port: number,
) => Promise<lsp.BaseLanguageClient>;

Expand Down Expand Up @@ -175,7 +176,7 @@ function getInitializationOptions(
mode: 'main-language-features' | 'second-language-features' | 'document-features',
useSecondServer: boolean,
) {
const initializationOptions: shared.ServerInitializationOptions = {
const initializationOptions: ServerInitializationOptions = {
typescript: tsVersion.getCurrentTsPaths(context),
languageFeatures: (mode === 'main-language-features' || mode === 'second-language-features') ? {
...(mode === 'main-language-features' ? {
Expand Down
4 changes: 2 additions & 2 deletions extensions/vscode-vue-language-features/client.js
@@ -1,6 +1,6 @@
try {
module.exports = require('./out/nodeClientMain');
module.exports = require('./out/nodeClientMain');
}
catch {
module.exports = require('./dist/node/client');
module.exports = require('./dist/node/client');
}
Expand Up @@ -25,11 +25,11 @@ require('esbuild').build({
return { path: path }
})
build.onResolve({ filter: /\/tsVersion$/ }, args => {
const path = require.resolve(args.path.replace('/tsVersion', '/tsVersionEmpty'), { paths: [args.resolveDir] })
const path = require.resolve(args.path.replace('/tsVersion', '/empty'), { paths: [args.resolveDir] })
return { path: path }
})
build.onResolve({ filter: /\/preview$/ }, args => {
const path = require.resolve(args.path.replace('/preview', '/tsVersionEmpty'), { paths: [args.resolveDir] })
const path = require.resolve(args.path.replace('/preview', '/empty'), { paths: [args.resolveDir] })
return { path: path }
})
},
Expand All @@ -56,6 +56,7 @@ require('esbuild').build({
external: ['fs'],
format: 'iife',
tsconfig: '../../tsconfig.build.json',
inject: ['./scripts/process-shim.js'],
minify: process.argv.includes('--minify'),
watch: process.argv.includes('--watch'),
plugins: [
Expand Down
@@ -0,0 +1,8 @@
// https://esbuild.github.io/api/#inject

let _cwd = '/'

export let process = {
cwd: () => _cwd,
chdir: newCwd => _cwd = newCwd,
}
4 changes: 2 additions & 2 deletions extensions/vscode-vue-language-features/server.js
@@ -1,6 +1,6 @@
try {
module.exports = require('./node_modules/@volar/vue-language-server/out/node');
module.exports = require('@volar/vue-language-server/bin/vue-language-server');
}
catch {
module.exports = require('./dist/node/server');
module.exports = require('./dist/node/server');
}
Expand Up @@ -29,7 +29,7 @@ export function activate(context: vscode.ExtensionContext) {
await client.start();

return client;
}, 'browser');
});
}

export function deactivate(): Thenable<any> | undefined {
Expand Down
25 changes: 14 additions & 11 deletions extensions/vscode-vue-language-features/src/common.ts
Expand Up @@ -18,6 +18,8 @@ import * as tsconfig from './features/tsconfig';
import * as doctor from './features/doctor';
import * as fileReferences from './features/fileReferences';
import * as reloadProject from './features/reloadProject';
import * as serverSys from './features/serverSys';
import { GetDocumentNameCasesRequest, ServerInitializationOptions } from '@volar/vue-language-server';

let apiClient: lsp.BaseLanguageClient | undefined;
let docClient: lsp.BaseLanguageClient | undefined;
Expand All @@ -27,11 +29,11 @@ type CreateLanguageClient = (
id: string,
name: string,
documentSelector: lsp.DocumentSelector,
initOptions: shared.ServerInitializationOptions,
initOptions: ServerInitializationOptions,
port: number,
) => Promise<lsp.BaseLanguageClient>;

export async function activate(context: vscode.ExtensionContext, createLc: CreateLanguageClient, env: 'node' | 'browser') {
export async function activate(context: vscode.ExtensionContext, createLc: CreateLanguageClient) {

const stopCheck = vscode.window.onDidChangeActiveTextEditor(tryActivate);
tryActivate();
Expand All @@ -40,26 +42,26 @@ export async function activate(context: vscode.ExtensionContext, createLc: Creat

if (!vscode.window.activeTextEditor) {
// onWebviewPanel:preview
doActivate(context, createLc, env);
doActivate(context, createLc);
stopCheck.dispose();
return;
}

const currentlangId = vscode.window.activeTextEditor.document.languageId;
if (currentlangId === 'vue' || currentlangId === 'markdown' || currentlangId === 'html') {
doActivate(context, createLc, env);
doActivate(context, createLc);
stopCheck.dispose();
}

const takeOverMode = takeOverModeEnabled();
if (takeOverMode && ['javascript', 'typescript', 'javascriptreact', 'typescriptreact'].includes(currentlangId)) {
doActivate(context, createLc, env);
doActivate(context, createLc);
stopCheck.dispose();
}
}
}

async function doActivate(context: vscode.ExtensionContext, createLc: CreateLanguageClient, env: 'node' | 'browser') {
async function doActivate(context: vscode.ExtensionContext, createLc: CreateLanguageClient) {

vscode.commands.executeCommand('setContext', 'volar.activated', true);

Expand Down Expand Up @@ -97,14 +99,14 @@ async function doActivate(context: vscode.ExtensionContext, createLc: CreateLang
const _serverMaxOldSpaceSize = serverMaxOldSpaceSize();

[apiClient, docClient, htmlClient] = await Promise.all([
env === 'node' ? createLc(
createLc(
'volar-language-features',
'Volar - Language Features Server',
languageFeaturesDocumentSelector,
getInitializationOptions(context, 'main-language-features', _useSecondServer),
6009,
) : undefined,
env === 'node' && _useSecondServer ? createLc(
),
_useSecondServer ? createLc(
'volar-language-features-2',
'Volar - Second Language Features Server',
languageFeaturesDocumentSelector,
Expand Down Expand Up @@ -183,6 +185,7 @@ async function doActivate(context: vscode.ExtensionContext, createLc: CreateLang
showReferences.activate(context, client);
documentContent.activate(context, client);
activeSelection.activate(context, client);
serverSys.activate(context, client);
}

(async () => {
Expand All @@ -191,7 +194,7 @@ async function doActivate(context: vscode.ExtensionContext, createLc: CreateLang
const getTagNameCase = await tagNameCase.activate(context, apiClient);
const getAttrNameCase = await attrNameCase.activate(context, apiClient);

apiClient.onRequest(shared.GetDocumentNameCasesRequest.type, async handler => ({
apiClient.onRequest(GetDocumentNameCasesRequest.type, async handler => ({
tagNameCase: getTagNameCase(handler.uri),
attrNameCase: getAttrNameCase(handler.uri),
}));
Expand Down Expand Up @@ -233,7 +236,7 @@ function getInitializationOptions(
mode: 'main-language-features' | 'second-language-features' | 'document-features',
useSecondServer: boolean,
) {
const initializationOptions: shared.ServerInitializationOptions = {
const initializationOptions: ServerInitializationOptions = {
typescript: tsVersion.getCurrentTsPaths(context),
languageFeatures: (mode === 'main-language-features' || mode === 'second-language-features') ? {
...(mode === 'main-language-features' ? {
Expand Down
@@ -1,9 +1,9 @@
import * as vscode from 'vscode';
import * as shared from '@volar/shared';
import type { BaseLanguageClient } from 'vscode-languageclient';
import { GetEditorSelectionRequest } from '@volar/vue-language-server';

export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {
context.subscriptions.push(languageClient.onRequest(shared.GetEditorSelectionRequest.type, () => {
context.subscriptions.push(languageClient.onRequest(GetEditorSelectionRequest.type, () => {
const editor = vscode.window.activeTextEditor;
if (editor) {
return {
Expand Down
Expand Up @@ -2,6 +2,7 @@ import * as vscode from 'vscode';
import { userPick } from './splitEditors';
import { BaseLanguageClient, State } from 'vscode-languageclient';
import * as shared from '@volar/shared';
import { DetectDocumentNameCasesRequest } from '@volar/vue-language-server';

export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {

Expand Down Expand Up @@ -41,7 +42,7 @@ export async function activate(context: vscode.ExtensionContext, languageClient:
updateStatusBarText('camelCase');
}
if (select === '6') {
const detects = await languageClient.sendRequest(shared.DetectDocumentNameCasesRequest.type, languageClient.code2ProtocolConverter.asTextDocumentIdentifier(crtDoc));
const detects = await languageClient.sendRequest(DetectDocumentNameCasesRequest.type, languageClient.code2ProtocolConverter.asTextDocumentIdentifier(crtDoc));
if (detects) {
attrCases.uriSet(crtDoc.uri.toString(), getValidAttrCase(detects.attr));
updateStatusBarText(getValidAttrCase(detects.attr));
Expand Down Expand Up @@ -82,7 +83,7 @@ export async function activate(context: vscode.ExtensionContext, languageClient:
attrCase = 'camelCase';
}
else {
const templateCases = await languageClient.sendRequest(shared.DetectDocumentNameCasesRequest.type, languageClient.code2ProtocolConverter.asTextDocumentIdentifier(newDoc));
const templateCases = await languageClient.sendRequest(DetectDocumentNameCasesRequest.type, languageClient.code2ProtocolConverter.asTextDocumentIdentifier(newDoc));
if (templateCases) {
attrCase = getValidAttrCase(templateCases.attr);
if (templateCases.attr === 'both') {
Expand Down
@@ -1,6 +1,6 @@
import * as vscode from 'vscode';
import * as shared from '@volar/shared';
import type { BaseLanguageClient } from 'vscode-languageclient';
import { AutoInsertRequest } from '@volar/vue-language-server';

export async function register(context: vscode.ExtensionContext, htmlClient: BaseLanguageClient, tsClient: BaseLanguageClient) {

Expand Down Expand Up @@ -62,8 +62,8 @@ export async function register(context: vscode.ExtensionContext, htmlClient: Bas
},
};

const result = await htmlClient.sendRequest(shared.AutoInsertRequest.type, params)
?? await tsClient.sendRequest(shared.AutoInsertRequest.type, params);
const result = await htmlClient.sendRequest(AutoInsertRequest.type, params)
?? await tsClient.sendRequest(AutoInsertRequest.type, params);

if (typeof result === 'string') {
return result;
Expand Down
@@ -1,13 +1,13 @@
import * as vscode from 'vscode';
import * as shared from '@volar/shared';
import type { BaseLanguageClient } from 'vscode-languageclient';
import { D3Request } from '@volar/vue-language-server';

export async function register(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {
context.subscriptions.push(vscode.commands.registerCommand('volar.action.showCallGraph', async () => {
const document = vscode.window.activeTextEditor?.document;
if (!document) return;
let param = languageClient.code2ProtocolConverter.asTextDocumentIdentifier(document);
const d3 = await languageClient.sendRequest(shared.D3Request.type, param);
const d3 = await languageClient.sendRequest(D3Request.type, param);

const panel = vscode.window.createWebviewPanel(
'vueCallGraph',
Expand Down
@@ -1,16 +1,16 @@
import * as vscode from 'vscode';
import { ResponseError } from 'vscode-languageclient';
import * as shared from '@volar/shared';
import type { BaseLanguageClient } from 'vscode-languageclient';
import * as nls from 'vscode-nls';
import { GetDocumentContentRequest } from '@volar/vue-language-server';

const localize = nls.loadMessageBundle();

export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {

const schemaDocuments: { [uri: string]: boolean; } = {};

context.subscriptions.push(languageClient.onRequest(shared.GetDocumentContentRequest.type, handle => {
context.subscriptions.push(languageClient.onRequest(GetDocumentContentRequest.type, handle => {
const uri = vscode.Uri.parse(handle.uri);
if (uri.scheme === 'untitled') {
return Promise.reject(new ResponseError(3, localize('untitled.schema', 'Unable to load {0}', uri.toString())));
Expand Down
@@ -1,2 +1,3 @@
export function activate() { }
export function getCurrentTsPaths() { }
export function register() { }
@@ -1,7 +1,7 @@
import * as vscode from 'vscode';
import { BaseLanguageClient } from 'vscode-languageclient';
import * as shared from '@volar/shared';
import * as nls from 'vscode-nls';
import { FindFileReferenceRequest } from '@volar/vue-language-server';

const localize = nls.loadMessageBundle();

Expand All @@ -21,7 +21,7 @@ export async function register(cmd: string, client: BaseLanguageClient) {
uri = editor.document.uri;
}

const response = await client.sendRequest(shared.FindFileReferenceRequest.type, { textDocument: { uri: uri.toString() } });
const response = await client.sendRequest(FindFileReferenceRequest.type, { textDocument: { uri: uri.toString() } });
if (!response) {
return;
}
Expand Down
@@ -1,12 +1,12 @@
import * as vscode from 'vscode';
import * as shared from '@volar/shared';
import type { BaseLanguageClient } from 'vscode-languageclient';
import { ReloadProjectNotification } from '@volar/vue-language-server';

export async function register(cmd: string, context: vscode.ExtensionContext, languageClients: BaseLanguageClient[]) {
context.subscriptions.push(vscode.commands.registerCommand(cmd, () => {
if (vscode.window.activeTextEditor) {
for (const client of languageClients) {
client.sendNotification(shared.ReloadProjectNotification.type, client.code2ProtocolConverter.asTextDocumentIdentifier(vscode.window.activeTextEditor.document));
client.sendNotification(ReloadProjectNotification.type, client.code2ProtocolConverter.asTextDocumentIdentifier(vscode.window.activeTextEditor.document));
}
}
}));
Expand Down
34 changes: 34 additions & 0 deletions extensions/vscode-vue-language-features/src/features/serverSys.ts
@@ -0,0 +1,34 @@
import * as vscode from 'vscode';
import type { BaseLanguageClient } from 'vscode-languageclient';
import { FsReadDirectoryRequest, FsReadFileRequest, FsStatRequest } from '@volar/vue-language-server';

export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {

context.subscriptions.push(languageClient.onRequest(FsStatRequest.type, async uri => {
try {
return await vscode.workspace.fs.stat(languageClient.protocol2CodeConverter.asUri(uri));
}
catch {
return undefined;
}
}));

context.subscriptions.push(languageClient.onRequest(FsReadFileRequest.type, async uri => {
try {
const data = await vscode.workspace.fs.readFile(languageClient.protocol2CodeConverter.asUri(uri));
return new TextDecoder('utf8').decode(data);
}
catch {
return undefined;
}
}));

context.subscriptions.push(languageClient.onRequest(FsReadDirectoryRequest.type, async uri => {
try {
return await vscode.workspace.fs.readDirectory(languageClient.protocol2CodeConverter.asUri(uri));
}
catch {
return [];
}
}));
}
@@ -1,9 +1,9 @@
import * as vscode from 'vscode';
import * as shared from '@volar/shared';
import type { BaseLanguageClient } from 'vscode-languageclient';
import { ShowReferencesNotification } from '@volar/vue-language-server';

export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {
context.subscriptions.push(languageClient.onNotification(shared.ShowReferencesNotification.type, handler => {
context.subscriptions.push(languageClient.onNotification(ShowReferencesNotification.type, handler => {
const uri = handler.textDocument.uri;
const pos = handler.position;
const refs = handler.references;
Expand Down
Expand Up @@ -2,6 +2,7 @@ import * as vscode from 'vscode';
import { userPick } from './splitEditors';
import { BaseLanguageClient, State } from 'vscode-languageclient';
import * as shared from '@volar/shared';
import { DetectDocumentNameCasesRequest } from '@volar/vue-language-server';

export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {

Expand Down Expand Up @@ -49,7 +50,7 @@ export async function activate(context: vscode.ExtensionContext, languageClient:
updateStatusBarText('pascalCase');
}
if (select === '3') {
const detects = await languageClient.sendRequest(shared.DetectDocumentNameCasesRequest.type, languageClient.code2ProtocolConverter.asTextDocumentIdentifier(crtDoc));
const detects = await languageClient.sendRequest(DetectDocumentNameCasesRequest.type, languageClient.code2ProtocolConverter.asTextDocumentIdentifier(crtDoc));
if (detects) {
tagCases.uriSet(crtDoc.uri.toString(), detects.tag);
updateStatusBarText(detects.tag);
Expand Down Expand Up @@ -115,7 +116,7 @@ export async function activate(context: vscode.ExtensionContext, languageClient:
tagCase = 'pascalCase';
}
else {
const templateCases = await languageClient.sendRequest(shared.DetectDocumentNameCasesRequest.type, languageClient.code2ProtocolConverter.asTextDocumentIdentifier(newDoc));
const templateCases = await languageClient.sendRequest(DetectDocumentNameCasesRequest.type, languageClient.code2ProtocolConverter.asTextDocumentIdentifier(newDoc));
tagCase = templateCases?.tag;
}
}
Expand Down

0 comments on commit c322297

Please sign in to comment.