Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upstream updates #63

Merged
merged 5 commits into from
Oct 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 10 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,16 @@ Do you want to use TypeScript/SCSS/Less/..? [See the docs](/docs/README.md#langu

## Features

- Svelte
- Diagnostic messages for warnings and errors
- Support for svelte preprocessors that provide source maps
- Svelte specific formatting (via [prettier-plugin-svelte](https://github.com/sveltejs/prettier-plugin-svelte))
- HTML
- Hover info
- Autocompletions
- [Emmet](https://emmet.io/)
- Symbols in Outline panel
- CSS / SCSS / LESS
- Diagnostic messages for syntax and lint errors
- Hover info
- Autocompletions
- Formatting (via [prettier](https://github.com/prettier/prettier))
- [Emmet](https://emmet.io/)
- Color highlighting and color picker
- Symbols in Outline panel
- TypeScript / JavaScript
- Diagnostics messages for syntax errors, semantic errors, and suggestions
- Hover info
- Formatting (via [prettier](https://github.com/prettier/prettier))
- Symbols in Outline panel
- Autocompletions
- Go to definition
- Code Actions
You can expect the following within Svelte files:

- Diagnostic messages
- Support for svelte preprocessors that provide source maps
- Formatting (via [prettier-plugin-svelte](https://github.com/sveltejs/prettier-plugin-svelte))
- Hover info
- Autocompletions
- Go to definition

The extension also comes packaged with a TypeScript plugin, which when activated provides intellisense within JavaScript and TypeScript files for interacting with Svelte files.

##### `svelte.plugin.XXX`

Expand Down
109 changes: 87 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@
},
"activationEvents": [
"onLanguage:svelte",
"onCommand:svelte.restartLanguageServer"
"onCommand:svelte.restartLanguageServer",
"onLanguage:javascript",
"onLanguage:typescript"
],
"contributes": {
"typescriptServerPlugins-disabled": [
"typescriptServerPlugins": [
{
"name": "typescript-svelte-plugin",
"enableForWorkspaceTypeScriptVersions": true
Expand Down Expand Up @@ -63,26 +65,35 @@
"scope": "application",
"type": "string",
"title": "Language Server Path",
"description": "- You normally don't set this - Path to the language server executable. If you installed the \"svelte-language-server\" npm package, it's within there at \"bin/server.js\". Path can be either relative to your workspace root or absolute. Set this only if you want to use a custom version of the language server. This setting can only be changed in user settings for security reasons."
"description": "- You normally don't set this - Path to the language server executable. If you installed the \"svelte-language-server\" npm package, it's within there at \"bin/server.js\". Path can be either relative to your workspace root or absolute. Set this only if you want to use a custom version of the language server. This will then also use the workspace version of TypeScript. This setting can only be changed in user settings for security reasons."
},
"svelte.language-server.port": {
"type": "number",
"title": "Language Server Port",
"description": "- You normally don't set this - At which port to spawn the language server. Can be used for attaching to the process for debugging / profiling. If you experience crashes due to \"port already in use\", try setting the port. -1 = default port is used.",
"default": -1
},
"svelte.language-server.debug": {
"type": "boolean",
"title": "Language Server Debug Mode",
"description": "- You normally don't set this - Enable more verbose logging for the language server useful for debugging language server execution."
},
"svelte.ui.svelteKitFilesContextMenu.enable": {
"type": "string",
"default": "auto",
"enum": [
"auto",
"never",
"always"
],
"description": "Show a context menu to generate SvelteKit files. \"always\" to always show it. \"never\" to always disable it. \"auto\" to show it when in a SvelteKit project. "
},
"svelte.plugin.typescript.enable": {
"type": "boolean",
"default": true,
"title": "TypeScript",
"description": "Enable the TypeScript plugin"
},
"svelte.plugin.typescript.findReferences.enable": {
"type": "boolean",
"default": true,
"title": "TypeScript: Find References",
"description": "Enable find-references for TypeScript"
},
"svelte.plugin.typescript.diagnostics.enable": {
"type": "boolean",
"default": true,
Expand Down Expand Up @@ -125,12 +136,6 @@
"title": "TypeScript: Signature Help",
"description": "Enable signature help (parameter hints) for TypeScript"
},
"svelte.plugin.typescript.rename.enable": {
"type": "boolean",
"default": true,
"title": "TypeScript: Rename",
"description": "Enable rename functionality for JS/TS variables inside Svelte files"
},
"svelte.plugin.typescript.codeActions.enable": {
"type": "boolean",
"default": true,
Expand Down Expand Up @@ -323,6 +328,16 @@
"default": true,
"title": "Svelte: Rename",
"description": "Enable rename/move Svelte files functionality"
},
"svelte.plugin.svelte.defaultScriptLanguage": {
"type": "string",
"default": "none",
"title": "Svelte: Default Script Language",
"description": "The default language to use when generating new script tags",
"enum": [
"none",
"ts"
]
}
}
},
Expand All @@ -340,6 +355,56 @@
{
"command": "svelte.restartLanguageServer",
"title": "Svelte: Restart Language Server"
},
{
"command": "svelte.typescript.findAllFileReferences",
"title": "Svelte: Find File References"
},
{
"command": "svelte.typescript.findComponentReferences",
"title": "Svelte: Find Component References"
},
{
"command": "svelte.kit.generateMultipleFiles",
"title": "SvelteKit: Create route"
},
{
"command": "svelte.kit.generatePage",
"title": "SvelteKit: Create +page.svelte"
},
{
"command": "svelte.kit.generatePageLoad",
"title": "SvelteKit: Create +page.js/ts"
},
{
"command": "svelte.kit.generatePageServerLoad",
"title": "SvelteKit: Create +page.server.js/ts"
},
{
"command": "svelte.kit.generateLayout",
"title": "SvelteKit: Create +layout.svelte"
},
{
"command": "svelte.kit.generateLayoutLoad",
"title": "SvelteKit: Create +layout.js/ts"
},
{
"command": "svelte.kit.generateLayoutServerLoad",
"title": "SvelteKit: Create +layout.server.js/ts"
},
{
"command": "svelte.kit.generateServer",
"title": "SvelteKit: Create +server.js/ts"
},
{
"command": "svelte.kit.generateError",
"title": "SvelteKit: Create +error.svelte"
}
],
"submenus": [
{
"id": "sveltekit2files",
"label": "SvelteKit Files"
}
],
"breakpoints": [
Expand All @@ -350,16 +415,16 @@
},
"dependencies": {
"lodash": "^4.17.21",
"svelte-language-server": "^0.14.9",
"typescript": "^4.4.3",
"typescript-svelte-plugin": "^0.2.4",
"vscode-languageserver-protocol": "^3.15.3"
"svelte-language-server": "*",
"typescript": "*",
"typescript-svelte-plugin": "*",
"vscode-languageserver-protocol": "^3.17.3"
},
"devDependencies": {
"@tsconfig/node12": "^1.0.0",
"@tsconfig/node14": "^1.0.0",
"@types/lodash": "^4.14.172",
"@types/node": "^14.0.1",
"coc.nvim": "^0.0.80",
"@types/node": "^14.0.0",
"coc.nvim": "^0.0.83-next.17",
"js-yaml": "^3.14.0",
"npm-run-all": "^4.1.5",
"rimraf": "^3.0.2"
Expand Down
93 changes: 79 additions & 14 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
window,
workspace,
services,
ExtensionContext,
LanguageClient,
LanguageClientOptions,
Expand All @@ -14,9 +15,60 @@ import {
import path from 'path';
import { Position, TextDocumentPositionParams } from 'vscode-languageserver-protocol';
import { activateTagClosing } from './html/autoClose';
import { addFindComponentReferencesListener } from './typescript/findComponentReferences';
import { addFindFileReferencesListener } from './typescript/findFileReferences';
import { TsPlugin } from './tsplugin';
import { setupSvelteKit } from './sveltekit';

let lsApi: { getLS(): LanguageClient } | undefined;

export function activate(context: ExtensionContext) {
// The extension is activated on TS/JS/Svelte files because else it might be too late to configure the TS plugin:
// If we only activate on Svelte file and the user opens a TS file first, the configuration command is issued too late.
// We wait until there's a Svelte file open and only then start the actual language client.
const tsPlugin = new TsPlugin(context);

if (workspace.textDocuments.some((doc) => doc.languageId === 'svelte')) {
lsApi = activateSvelteLanguageServer(context);
tsPlugin.askToEnable();
} else {
const onTextDocumentListener = workspace.onDidOpenTextDocument((doc) => {
if (doc.languageId === 'svelte') {
lsApi = activateSvelteLanguageServer(context);
tsPlugin.askToEnable();
onTextDocumentListener.dispose();
}
});

context.subscriptions.push(onTextDocumentListener);
}

setupSvelteKit(context);

// This API is considered private and only exposed for experimenting.
// Interface may change at any time. Use at your own risk!
return {
/**
* As a function, because restarting the server
* will result in another instance.
*/
getLanguageServer() {
if (!lsApi) {
lsApi = activateSvelteLanguageServer(context);
}

return lsApi.getLS();
},
};
}

export function deactivate() {
const stop = lsApi?.getLS().stop();
lsApi = undefined;
return stop;
}

export function activateSvelteLanguageServer(context: ExtensionContext) {
const runtimeConfig = workspace.getConfiguration('svelte.language-server');

const { workspaceFolders } = workspace;
Expand Down Expand Up @@ -66,16 +118,24 @@ export function activate(context: ExtensionContext) {
documentSelector: [{ scheme: 'file', language: 'svelte' }],
revealOutputChannelOn: RevealOutputChannelOn.Never,
synchronize: {
configurationSection: ['svelte', 'javascript', 'typescript', 'prettier'],
configurationSection: [
'svelte',
'javascript',
'typescript',
'prettier',
'css',
'less',
'scss',
'html',
],
fileEvents: workspace.createFileSystemWatcher('{**/*.js,**/*.ts}', false, false, false),
},
initializationOptions: { config: workspace.getConfiguration('svelte.plugin') },
};

let ls = createLanguageServer(serverOptions, clientOptions);
context.subscriptions.push(ls.start());

ls.onReady().then(() => {
ls.start().then(() => {
const tagRequestor = (document: TextDocument, position: Position) => {
const param: TextDocumentPositionParams = {
textDocument: { uri: document.uri },
Expand All @@ -89,7 +149,7 @@ export function activate(context: ExtensionContext) {
'html.autoClosingTags',
);
context.subscriptions.push(disposable);
window.showMessage('Svelte language server now active.');
window.showInformationMessage('Svelte language server now active.');
});

context.subscriptions.push(
Expand All @@ -100,27 +160,31 @@ export function activate(context: ExtensionContext) {
async function restartLS(showNotification: boolean) {
await ls.stop();
ls = createLanguageServer(serverOptions, clientOptions);
context.subscriptions.push(ls.start());
await ls.onReady();
if (showNotification) {
window.showMessage('Svelte language server restarted.');
}
context.subscriptions.push(services.registerLanguageClient(ls));
await ls.onReady().then(() => {
if (showNotification) {
window.showInformationMessage('Svelte language server restarted.');
}
});
}

function getLS() {
return ls;
}

context.subscriptions.push(addDidChangeTextDocumentListener(getLS));

TsPlugin.create(context);
addDidChangeTextDocumentListener(getLS, context);
addFindFileReferencesListener(getLS, context);
addFindComponentReferencesListener(getLS, context);
return {
getLS,
};
}

function addDidChangeTextDocumentListener(getLS: () => LanguageClient) {
function addDidChangeTextDocumentListener(getLS: () => LanguageClient, context: ExtensionContext) {
// Only Svelte file changes are automatically notified through the inbuilt LSP
// because the extension says it's only responsible for Svelte files.
// Therefore we need to set this up for TS/JS files manually.
return workspace.onDidChangeTextDocument((evt) => {
const disposable = workspace.onDidChangeTextDocument((evt) => {
if (evt.textDocument.uri.endsWith('.ts') || evt.textDocument.uri.endsWith('.js')) {
getLS().sendNotification('$/onDidChangeTsOrJsFile', {
uri: evt.textDocument.uri,
Expand All @@ -134,6 +198,7 @@ function addDidChangeTextDocumentListener(getLS: () => LanguageClient) {
});
}
});
context.subscriptions.push(disposable);
}

function createLanguageServer(serverOptions: ServerOptions, clientOptions: LanguageClientOptions) {
Expand Down
12 changes: 12 additions & 0 deletions src/sveltekit/generateFiles/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { CommandType, ResourceType } from './types';

export const addResourceCommandMap = new Map<CommandType, ResourceType>([
[CommandType.PAGE, ResourceType.PAGE],
[CommandType.PAGE_LOAD, ResourceType.PAGE_LOAD],
[CommandType.PAGE_SERVER, ResourceType.PAGE_SERVER],
[CommandType.LAYOUT, ResourceType.LAYOUT],
[CommandType.LAYOUT_LOAD, ResourceType.LAYOUT_LOAD],
[CommandType.LAYOUT_SERVER, ResourceType.LAYOUT_SERVER],
[CommandType.SERVER, ResourceType.SERVER],
[CommandType.ERROR, ResourceType.ERROR],
]);
Loading