Feat: first work for rsx vscode ext
This commit is contained in:
1 parent
65d0d611ea
commit
2e626aea51
27 files changed
+4701
-31
No files matched your search
@@ -10,6 +10,8 @@ members = [
|
|||||||
"packages/router",
|
"packages/router",
|
||||||
"packages/ssr",
|
"packages/ssr",
|
||||||
"packages/webview",
|
"packages/webview",
|
||||||
|
# Not a rust package, :(. One day, maybe
|
||||||
|
"packages/vscode-ext",
|
||||||
# "packages/macro",
|
# "packages/macro",
|
||||||
# TODO @Jon, share the validation code
|
# TODO @Jon, share the validation code
|
||||||
# "packages/web",
|
# "packages/web",
|
||||||
|
|||||||
@@ -46,7 +46,5 @@ pub mod logger {
|
|||||||
.chain(std::io::stdout())
|
.chain(std::io::stdout())
|
||||||
.apply()
|
.apply()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
debug!("finished setting up logging! yay!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,6 @@ fn main() {
|
|||||||
|
|
||||||
<head>
|
<head>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
fn main() {
|
//! Example: Hello-web
|
||||||
println!("Hello world!");
|
//! -----------------
|
||||||
println!("Hello world!");
|
//!
|
||||||
println!("Hello world!");
|
//! This example showcases Dioxus-websys to build interactive single-page-applications, much like React.
|
||||||
println!("Hello world!");
|
|
||||||
println!("Hello world!");
|
fn main() {}
|
||||||
println!("Hello world!");
|
|
||||||
println!("Hello world!");
|
|
||||||
}
|
|
||||||
+7
-5
@@ -1,9 +1,11 @@
|
|||||||
//! Dioxus Router
|
//! Dioxus Router
|
||||||
|
//! -------------
|
||||||
|
//!
|
||||||
|
//! This exmaple showcases the Dioxus Router hook. This hook makes it possible to using the browser's navigation API to
|
||||||
|
//! display different content based on the Page's URL. The hook provides a configuration object that calls various
|
||||||
|
//! specified callbacks whenever the page URL changes. Using this hook should feel like building a "URL directory", similar
|
||||||
|
//! to how Tide handles paths.
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {}
|
||||||
// let mut app = App::new();
|
|
||||||
|
|
||||||
// app.at(c)
|
|
||||||
}
|
|
||||||
+21
-14
@@ -1,3 +1,6 @@
|
|||||||
|
//! Example: Tide Server-Side-Rendering
|
||||||
|
//! -----------------------------------
|
||||||
|
//!
|
||||||
//! This demo shows how to use the to_string utility on VNodes to convert them into valid HTML.
|
//! This demo shows how to use the to_string utility on VNodes to convert them into valid HTML.
|
||||||
//! You can use the html! macro to craft webpages generated by the server on-the-fly.
|
//! You can use the html! macro to craft webpages generated by the server on-the-fly.
|
||||||
//!
|
//!
|
||||||
@@ -5,6 +8,7 @@
|
|||||||
//! thousands of simultaneous clients on minimal hardware.
|
//! thousands of simultaneous clients on minimal hardware.
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
use rand::Rng;
|
||||||
use tide::{Request, Response};
|
use tide::{Request, Response};
|
||||||
|
|
||||||
#[async_std::main]
|
#[async_std::main]
|
||||||
@@ -18,35 +22,38 @@ async fn main() -> Result<(), std::io::Error> {
|
|||||||
// Launch the server
|
// Launch the server
|
||||||
let addr = "127.0.0.1:8080";
|
let addr = "127.0.0.1:8080";
|
||||||
log::info!("App is ready at {}", addr);
|
log::info!("App is ready at {}", addr);
|
||||||
log::info!("Navigate to an fibonacci number, like so http://localhost:8080/fib/21");
|
log::info!("Navigate to a fibonacci number: http://{}/fib/21", addr);
|
||||||
app.listen(addr).await?;
|
app.listen(addr).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fib(n: usize) -> usize {
|
||||||
|
if n == 0 || n == 1 {
|
||||||
|
n
|
||||||
|
} else {
|
||||||
|
fib(n - 1) + fib(n - 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Calculate the fibonacci number for a given request input
|
/// Calculate the fibonacci number for a given request input
|
||||||
async fn fibsum(req: Request<()>) -> tide::Result<tide::Response> {
|
async fn fibsum(req: Request<()>) -> tide::Result<tide::Response> {
|
||||||
use std::time::Instant;
|
|
||||||
let n: usize = req.param("n")?.parse().unwrap_or(0);
|
let n: usize = req.param("n")?.parse().unwrap_or(0);
|
||||||
|
|
||||||
fn fib(n: usize) -> usize {
|
|
||||||
if n == 0 || n == 1 {
|
|
||||||
n
|
|
||||||
} else {
|
|
||||||
fib(n - 1) + fib(n - 2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start a stopwatch
|
// Start a stopwatch
|
||||||
// Compute the nth number in the fibonacci sequence
|
// Compute the nth number in the fibonacci sequence
|
||||||
// Stop the stopwatch
|
// Stop the stopwatch
|
||||||
let start = Instant::now();
|
let start = std::time::Instant::now();
|
||||||
let fib_n = fib(n);
|
let fib_n = fib(n);
|
||||||
let duration = start.elapsed().as_nanos();
|
let duration = start.elapsed().as_nanos();
|
||||||
|
|
||||||
let mut rng = rand::thread_rng();
|
// Generate another random number to try
|
||||||
use rand::Rng;
|
let other_fib_to_try = rand::thread_rng().gen_range(1..42);
|
||||||
let other_fib_to_try = rng.gen_range(1..42);
|
|
||||||
|
let g = html! {
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
|
};
|
||||||
|
|
||||||
let nodes = html! {
|
let nodes = html! {
|
||||||
<html>
|
<html>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//! Example: Webview Renderer
|
//! Example: Webview Renderer
|
||||||
|
//! -------------------------
|
||||||
//!
|
//!
|
||||||
//! This example shows how to use the dioxus_webview crate to build a basic desktop application.
|
//! This example shows how to use the dioxus_webview crate to build a basic desktop application.
|
||||||
//!
|
//!
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
out
|
||||||
|
node_modules
|
||||||
|
client/server
|
||||||
|
.vscode-test
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
// A launch configuration that compiles the extension and then opens it inside a new window
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "extensionHost",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Launch Client",
|
||||||
|
"runtimeExecutable": "${execPath}",
|
||||||
|
"args": ["--extensionDevelopmentPath=${workspaceRoot}"],
|
||||||
|
"outFiles": ["${workspaceRoot}/client/out/**/*.js"],
|
||||||
|
"preLaunchTask": {
|
||||||
|
"type": "npm",
|
||||||
|
"script": "watch"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "attach",
|
||||||
|
"name": "Attach to Server",
|
||||||
|
"port": 6009,
|
||||||
|
"restart": true,
|
||||||
|
"outFiles": ["${workspaceRoot}/server/out/**/*.js"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Language Server E2E Test",
|
||||||
|
"type": "extensionHost",
|
||||||
|
"request": "launch",
|
||||||
|
"runtimeExecutable": "${execPath}",
|
||||||
|
"args": [
|
||||||
|
"--extensionDevelopmentPath=${workspaceRoot}",
|
||||||
|
"--extensionTestsPath=${workspaceRoot}/client/out/test",
|
||||||
|
"${workspaceRoot}/client/testFixture"
|
||||||
|
],
|
||||||
|
"outFiles": ["${workspaceRoot}/client/out/test/**/*.js"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"compounds": [
|
||||||
|
{
|
||||||
|
"name": "Client + Server",
|
||||||
|
"configurations": ["Launch Client", "Attach to Server"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "compile",
|
||||||
|
"group": "build",
|
||||||
|
"presentation": {
|
||||||
|
"panel": "dedicated",
|
||||||
|
"reveal": "never"
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$tsc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "watch",
|
||||||
|
"isBackground": true,
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"presentation": {
|
||||||
|
"panel": "dedicated",
|
||||||
|
"reveal": "never"
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$tsc-watch"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
.vscode/**
|
||||||
|
**/*.ts
|
||||||
|
**/*.map
|
||||||
|
.gitignore
|
||||||
|
**/tsconfig.json
|
||||||
|
**/tsconfig.base.json
|
||||||
|
contributing.md
|
||||||
|
.travis.yml
|
||||||
|
client/node_modules/**
|
||||||
|
!client/node_modules/vscode-jsonrpc/**
|
||||||
|
!client/node_modules/vscode-languageclient/**
|
||||||
|
!client/node_modules/vscode-languageserver-protocol/**
|
||||||
|
!client/node_modules/vscode-languageserver-types/**
|
||||||
|
!client/node_modules/semver/**
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "syntax-gen"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Jonathan Kelley <jkelleyrtp@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
path = "./rust/main.rs"
|
||||||
|
name = "main"
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# VSCode support for Dioxus html macro
|
||||||
|
|
||||||
|
This macro provides syntax highlighting for the html! macro used in Dioxus projects. Users should feel at home writing html and css alongside the custom attributes used by Dioxus.
|
||||||
|
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
This extension works by:
|
||||||
|
- Creating a custom HTML ruleset for dioxus html! nodes
|
||||||
|
- Request forwarding content
|
||||||
|
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
Request forwarding is performed intelligently by the extension.
|
||||||
|
Requests within the html! tag are forwarded to the html language service. It's simple and doesn't
|
||||||
|
|
||||||
|
https://code.visualstudio.com/api/language-extensions/embedded-languages#language-services
|
||||||
|
|
||||||
+76
@@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
"name": "lsp-sample-client",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"requires": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/vscode": {
|
||||||
|
"version": "1.43.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.43.0.tgz",
|
||||||
|
"integrity": "sha512-kIaR9qzd80rJOxePKpCB/mdy00mz8Apt2QA5Y6rdrKFn13QNFNeP3Hzmsf37Bwh/3cS7QjtAeGSK7wSqAU0sYQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"vscode-html-languageservice": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-U+upM3gHp3HaF3wXAnUduA6IDKcz6frWS/dTAju3cZVIyZwOLBBFElQVlLH0ycHyMzqUFrjvdv+kEyPAEWfQ/g==",
|
||||||
|
"requires": {
|
||||||
|
"vscode-languageserver-types": "^3.15.0-next.2",
|
||||||
|
"vscode-nls": "^4.1.1",
|
||||||
|
"vscode-uri": "^2.0.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"vscode-languageserver-types": {
|
||||||
|
"version": "3.15.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz",
|
||||||
|
"integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"vscode-jsonrpc": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A=="
|
||||||
|
},
|
||||||
|
"vscode-languageclient": {
|
||||||
|
"version": "6.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-6.1.3.tgz",
|
||||||
|
"integrity": "sha512-YciJxk08iU5LmWu7j5dUt9/1OLjokKET6rME3cI4BRpiF6HZlusm2ZwPt0MYJ0lV5y43sZsQHhyon2xBg4ZJVA==",
|
||||||
|
"requires": {
|
||||||
|
"semver": "^6.3.0",
|
||||||
|
"vscode-languageserver-protocol": "^3.15.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"semver": {
|
||||||
|
"version": "6.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"vscode-languageserver-protocol": {
|
||||||
|
"version": "3.15.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz",
|
||||||
|
"integrity": "sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw==",
|
||||||
|
"requires": {
|
||||||
|
"vscode-jsonrpc": "^5.0.1",
|
||||||
|
"vscode-languageserver-types": "3.15.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"vscode-languageserver-types": {
|
||||||
|
"version": "3.15.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz",
|
||||||
|
"integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ=="
|
||||||
|
},
|
||||||
|
"vscode-nls": {
|
||||||
|
"version": "4.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz",
|
||||||
|
"integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw=="
|
||||||
|
},
|
||||||
|
"vscode-uri": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-eY9jmGoEnVf8VE8xr5znSah7Qt1P/xsCdErz+g8HYZtJ7bZqKH5E3d+6oVNm1AC/c6IHUDokbmVXKOi4qPAC9A=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "lsp-sample-client",
|
||||||
|
"description": "VSCode part of a language server",
|
||||||
|
"author": "Microsoft Corporation",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"publisher": "vscode",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Microsoft/vscode-extension-samples"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"vscode": "^1.43.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"vscode-html-languageservice": "^3.0.3",
|
||||||
|
"vscode-languageclient": "^6.1.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/vscode": "^1.43.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,415 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { TextDocument, Position, Range } from 'vscode-languageclient';
|
||||||
|
import { LanguageService, TokenType } from 'vscode-html-languageservice';
|
||||||
|
|
||||||
|
export interface LanguageRange extends Range {
|
||||||
|
languageId: string | undefined;
|
||||||
|
attributeValue?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HTMLDocumentRegions {
|
||||||
|
getEmbeddedDocument(languageId: string, ignoreAttributeValues?: boolean): TextDocument;
|
||||||
|
getLanguageRanges(range: Range): LanguageRange[];
|
||||||
|
getLanguageAtPosition(position: Position): string | undefined;
|
||||||
|
getLanguagesInDocument(): string[];
|
||||||
|
getImportedScripts(): string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CSS_STYLE_RULE = '__';
|
||||||
|
|
||||||
|
interface EmbeddedRegion {
|
||||||
|
languageId: string | undefined;
|
||||||
|
start: number;
|
||||||
|
end: number;
|
||||||
|
attributeValue?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isInsideStyleRegion(
|
||||||
|
languageService: LanguageService,
|
||||||
|
documentText: string,
|
||||||
|
offset: number
|
||||||
|
) {
|
||||||
|
let scanner = languageService.createScanner(documentText);
|
||||||
|
|
||||||
|
let token = scanner.scan();
|
||||||
|
while (token !== TokenType.EOS) {
|
||||||
|
switch (token) {
|
||||||
|
case TokenType.Styles:
|
||||||
|
if (offset >= scanner.getTokenOffset() && offset <= scanner.getTokenEnd()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
token = scanner.scan();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCSSVirtualContent(
|
||||||
|
languageService: LanguageService,
|
||||||
|
documentText: string
|
||||||
|
): string {
|
||||||
|
let regions: EmbeddedRegion[] = [];
|
||||||
|
let scanner = languageService.createScanner(documentText);
|
||||||
|
let lastTagName: string = '';
|
||||||
|
let lastAttributeName: string | null = null;
|
||||||
|
let languageIdFromType: string | undefined = undefined;
|
||||||
|
let importedScripts: string[] = [];
|
||||||
|
|
||||||
|
let token = scanner.scan();
|
||||||
|
while (token !== TokenType.EOS) {
|
||||||
|
switch (token) {
|
||||||
|
case TokenType.StartTag:
|
||||||
|
lastTagName = scanner.getTokenText();
|
||||||
|
lastAttributeName = null;
|
||||||
|
languageIdFromType = 'javascript';
|
||||||
|
break;
|
||||||
|
case TokenType.Styles:
|
||||||
|
regions.push({
|
||||||
|
languageId: 'css',
|
||||||
|
start: scanner.getTokenOffset(),
|
||||||
|
end: scanner.getTokenEnd()
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case TokenType.Script:
|
||||||
|
regions.push({
|
||||||
|
languageId: languageIdFromType,
|
||||||
|
start: scanner.getTokenOffset(),
|
||||||
|
end: scanner.getTokenEnd()
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case TokenType.AttributeName:
|
||||||
|
lastAttributeName = scanner.getTokenText();
|
||||||
|
break;
|
||||||
|
case TokenType.AttributeValue:
|
||||||
|
if (lastAttributeName === 'src' && lastTagName.toLowerCase() === 'script') {
|
||||||
|
let value = scanner.getTokenText();
|
||||||
|
if (value[0] === "'" || value[0] === '"') {
|
||||||
|
value = value.substr(1, value.length - 1);
|
||||||
|
}
|
||||||
|
importedScripts.push(value);
|
||||||
|
} else if (lastAttributeName === 'type' && lastTagName.toLowerCase() === 'script') {
|
||||||
|
if (
|
||||||
|
/["'](module|(text|application)\/(java|ecma)script|text\/babel)["']/.test(
|
||||||
|
scanner.getTokenText()
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
languageIdFromType = 'javascript';
|
||||||
|
} else if (/["']text\/typescript["']/.test(scanner.getTokenText())) {
|
||||||
|
languageIdFromType = 'typescript';
|
||||||
|
} else {
|
||||||
|
languageIdFromType = undefined;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let attributeLanguageId = getAttributeLanguage(lastAttributeName!);
|
||||||
|
if (attributeLanguageId) {
|
||||||
|
let start = scanner.getTokenOffset();
|
||||||
|
let end = scanner.getTokenEnd();
|
||||||
|
let firstChar = documentText[start];
|
||||||
|
if (firstChar === "'" || firstChar === '"') {
|
||||||
|
start++;
|
||||||
|
end--;
|
||||||
|
}
|
||||||
|
regions.push({
|
||||||
|
languageId: attributeLanguageId,
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
attributeValue: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastAttributeName = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
token = scanner.scan();
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = documentText
|
||||||
|
.split('\n')
|
||||||
|
.map(line => {
|
||||||
|
return ' '.repeat(line.length);
|
||||||
|
}).join('\n');
|
||||||
|
|
||||||
|
regions.forEach(r => {
|
||||||
|
if (r.languageId === 'css') {
|
||||||
|
content = content.slice(0, r.start) + documentText.slice(r.start, r.end) + content.slice(r.end);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getDocumentRegions(
|
||||||
|
languageService: LanguageService,
|
||||||
|
document: TextDocument
|
||||||
|
): HTMLDocumentRegions {
|
||||||
|
let regions: EmbeddedRegion[] = [];
|
||||||
|
let scanner = languageService.createScanner(document.getText());
|
||||||
|
let lastTagName: string = '';
|
||||||
|
let lastAttributeName: string | null = null;
|
||||||
|
let languageIdFromType: string | undefined = undefined;
|
||||||
|
let importedScripts: string[] = [];
|
||||||
|
|
||||||
|
let token = scanner.scan();
|
||||||
|
while (token !== TokenType.EOS) {
|
||||||
|
switch (token) {
|
||||||
|
case TokenType.StartTag:
|
||||||
|
lastTagName = scanner.getTokenText();
|
||||||
|
lastAttributeName = null;
|
||||||
|
languageIdFromType = 'javascript';
|
||||||
|
break;
|
||||||
|
case TokenType.Styles:
|
||||||
|
regions.push({
|
||||||
|
languageId: 'css',
|
||||||
|
start: scanner.getTokenOffset(),
|
||||||
|
end: scanner.getTokenEnd()
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case TokenType.Script:
|
||||||
|
regions.push({
|
||||||
|
languageId: languageIdFromType,
|
||||||
|
start: scanner.getTokenOffset(),
|
||||||
|
end: scanner.getTokenEnd()
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case TokenType.AttributeName:
|
||||||
|
lastAttributeName = scanner.getTokenText();
|
||||||
|
break;
|
||||||
|
case TokenType.AttributeValue:
|
||||||
|
if (lastAttributeName === 'src' && lastTagName.toLowerCase() === 'script') {
|
||||||
|
let value = scanner.getTokenText();
|
||||||
|
if (value[0] === "'" || value[0] === '"') {
|
||||||
|
value = value.substr(1, value.length - 1);
|
||||||
|
}
|
||||||
|
importedScripts.push(value);
|
||||||
|
} else if (lastAttributeName === 'type' && lastTagName.toLowerCase() === 'script') {
|
||||||
|
if (
|
||||||
|
/["'](module|(text|application)\/(java|ecma)script|text\/babel)["']/.test(
|
||||||
|
scanner.getTokenText()
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
languageIdFromType = 'javascript';
|
||||||
|
} else if (/["']text\/typescript["']/.test(scanner.getTokenText())) {
|
||||||
|
languageIdFromType = 'typescript';
|
||||||
|
} else {
|
||||||
|
languageIdFromType = undefined;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let attributeLanguageId = getAttributeLanguage(lastAttributeName!);
|
||||||
|
if (attributeLanguageId) {
|
||||||
|
let start = scanner.getTokenOffset();
|
||||||
|
let end = scanner.getTokenEnd();
|
||||||
|
let firstChar = document.getText()[start];
|
||||||
|
if (firstChar === "'" || firstChar === '"') {
|
||||||
|
start++;
|
||||||
|
end--;
|
||||||
|
}
|
||||||
|
regions.push({
|
||||||
|
languageId: attributeLanguageId,
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
attributeValue: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastAttributeName = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
token = scanner.scan();
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
getLanguageRanges: (range: Range) => getLanguageRanges(document, regions, range),
|
||||||
|
getEmbeddedDocument: (languageId: string, ignoreAttributeValues: boolean) =>
|
||||||
|
getEmbeddedDocument(document, regions, languageId, ignoreAttributeValues),
|
||||||
|
getLanguageAtPosition: (position: Position) =>
|
||||||
|
getLanguageAtPosition(document, regions, position),
|
||||||
|
getLanguagesInDocument: () => getLanguagesInDocument(document, regions),
|
||||||
|
getImportedScripts: () => importedScripts
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLanguageRanges(
|
||||||
|
document: TextDocument,
|
||||||
|
regions: EmbeddedRegion[],
|
||||||
|
range: Range
|
||||||
|
): LanguageRange[] {
|
||||||
|
let result: LanguageRange[] = [];
|
||||||
|
let currentPos = range ? range.start : Position.create(0, 0);
|
||||||
|
let currentOffset = range ? document.offsetAt(range.start) : 0;
|
||||||
|
let endOffset = range ? document.offsetAt(range.end) : document.getText().length;
|
||||||
|
for (let region of regions) {
|
||||||
|
if (region.end > currentOffset && region.start < endOffset) {
|
||||||
|
let start = Math.max(region.start, currentOffset);
|
||||||
|
let startPos = document.positionAt(start);
|
||||||
|
if (currentOffset < region.start) {
|
||||||
|
result.push({
|
||||||
|
start: currentPos,
|
||||||
|
end: startPos,
|
||||||
|
languageId: 'html'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let end = Math.min(region.end, endOffset);
|
||||||
|
let endPos = document.positionAt(end);
|
||||||
|
if (end > region.start) {
|
||||||
|
result.push({
|
||||||
|
start: startPos,
|
||||||
|
end: endPos,
|
||||||
|
languageId: region.languageId,
|
||||||
|
attributeValue: region.attributeValue
|
||||||
|
});
|
||||||
|
}
|
||||||
|
currentOffset = end;
|
||||||
|
currentPos = endPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentOffset < endOffset) {
|
||||||
|
let endPos = range ? range.end : document.positionAt(endOffset);
|
||||||
|
result.push({
|
||||||
|
start: currentPos,
|
||||||
|
end: endPos,
|
||||||
|
languageId: 'html'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLanguagesInDocument(
|
||||||
|
_document: TextDocument,
|
||||||
|
regions: EmbeddedRegion[]
|
||||||
|
): string[] {
|
||||||
|
let result = [];
|
||||||
|
for (let region of regions) {
|
||||||
|
if (region.languageId && result.indexOf(region.languageId) === -1) {
|
||||||
|
result.push(region.languageId);
|
||||||
|
if (result.length === 3) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.push('html');
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLanguageAtPosition(
|
||||||
|
document: TextDocument,
|
||||||
|
regions: EmbeddedRegion[],
|
||||||
|
position: Position
|
||||||
|
): string | undefined {
|
||||||
|
let offset = document.offsetAt(position);
|
||||||
|
for (let region of regions) {
|
||||||
|
if (region.start <= offset) {
|
||||||
|
if (offset <= region.end) {
|
||||||
|
return region.languageId;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'html';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEmbeddedDocument(
|
||||||
|
document: TextDocument,
|
||||||
|
contents: EmbeddedRegion[],
|
||||||
|
languageId: string,
|
||||||
|
ignoreAttributeValues: boolean
|
||||||
|
): TextDocument {
|
||||||
|
let currentPos = 0;
|
||||||
|
let oldContent = document.getText();
|
||||||
|
let result = '';
|
||||||
|
let lastSuffix = '';
|
||||||
|
for (let c of contents) {
|
||||||
|
if (c.languageId === languageId && (!ignoreAttributeValues || !c.attributeValue)) {
|
||||||
|
result = substituteWithWhitespace(
|
||||||
|
result,
|
||||||
|
currentPos,
|
||||||
|
c.start,
|
||||||
|
oldContent,
|
||||||
|
lastSuffix,
|
||||||
|
getPrefix(c)
|
||||||
|
);
|
||||||
|
result += oldContent.substring(c.start, c.end);
|
||||||
|
currentPos = c.end;
|
||||||
|
lastSuffix = getSuffix(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = substituteWithWhitespace(
|
||||||
|
result,
|
||||||
|
currentPos,
|
||||||
|
oldContent.length,
|
||||||
|
oldContent,
|
||||||
|
lastSuffix,
|
||||||
|
''
|
||||||
|
);
|
||||||
|
return TextDocument.create(document.uri, languageId, document.version, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPrefix(c: EmbeddedRegion) {
|
||||||
|
if (c.attributeValue) {
|
||||||
|
switch (c.languageId) {
|
||||||
|
case 'css':
|
||||||
|
return CSS_STYLE_RULE + '{';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
function getSuffix(c: EmbeddedRegion) {
|
||||||
|
if (c.attributeValue) {
|
||||||
|
switch (c.languageId) {
|
||||||
|
case 'css':
|
||||||
|
return '}';
|
||||||
|
case 'javascript':
|
||||||
|
return ';';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function substituteWithWhitespace(
|
||||||
|
result: string,
|
||||||
|
start: number,
|
||||||
|
end: number,
|
||||||
|
oldContent: string,
|
||||||
|
before: string,
|
||||||
|
after: string
|
||||||
|
) {
|
||||||
|
let accumulatedWS = 0;
|
||||||
|
result += before;
|
||||||
|
for (let i = start + before.length; i < end; i++) {
|
||||||
|
let ch = oldContent[i];
|
||||||
|
if (ch === '\n' || ch === '\r') {
|
||||||
|
// only write new lines, skip the whitespace
|
||||||
|
accumulatedWS = 0;
|
||||||
|
result += ch;
|
||||||
|
} else {
|
||||||
|
accumulatedWS++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = append(result, ' ', accumulatedWS - after.length);
|
||||||
|
result += after;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function append(result: string, str: string, n: number): string {
|
||||||
|
while (n > 0) {
|
||||||
|
if (n & 1) {
|
||||||
|
result += str;
|
||||||
|
}
|
||||||
|
n >>= 1;
|
||||||
|
str += str;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAttributeLanguage(attributeName: string): string | null {
|
||||||
|
let match = attributeName.match(/^(style)$|^(on\w+)$/i);
|
||||||
|
if (!match) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return match[1] ? 'css' : 'javascript';
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
* ------------------------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
import * as path from 'path';
|
||||||
|
import { commands, CompletionList, ExtensionContext, Uri, workspace } from 'vscode';
|
||||||
|
import { getLanguageService } from 'vscode-html-languageservice';
|
||||||
|
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient';
|
||||||
|
import { getCSSVirtualContent, isInsideStyleRegion } from './embeddedSupport';
|
||||||
|
|
||||||
|
let client: LanguageClient;
|
||||||
|
|
||||||
|
const htmlLanguageService = getLanguageService();
|
||||||
|
|
||||||
|
export function activate(context: ExtensionContext) {
|
||||||
|
// The server is implemented in node
|
||||||
|
let serverModule = context.asAbsolutePath(path.join('server', 'out', 'server.js'));
|
||||||
|
// The debug options for the server
|
||||||
|
// --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
|
||||||
|
let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };
|
||||||
|
|
||||||
|
// If the extension is launched in debug mode then the debug server options are used
|
||||||
|
// Otherwise the run options are used
|
||||||
|
let serverOptions: ServerOptions = {
|
||||||
|
run: { module: serverModule, transport: TransportKind.ipc },
|
||||||
|
debug: {
|
||||||
|
module: serverModule,
|
||||||
|
transport: TransportKind.ipc,
|
||||||
|
options: debugOptions
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const virtualDocumentContents = new Map<string, string>();
|
||||||
|
|
||||||
|
workspace.registerTextDocumentContentProvider('embedded-content', {
|
||||||
|
provideTextDocumentContent: uri => {
|
||||||
|
const originalUri = uri.path.slice(1).slice(0, -4);
|
||||||
|
const decodedUri = decodeURIComponent(originalUri);
|
||||||
|
return virtualDocumentContents.get(decodedUri);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let clientOptions: LanguageClientOptions = {
|
||||||
|
documentSelector: [{ scheme: 'file', language: 'html1' }],
|
||||||
|
middleware: {
|
||||||
|
provideCompletionItem: async (document, position, context, token, next) => {
|
||||||
|
// If not in `<style>`, do not perform request forwarding
|
||||||
|
if (!isInsideStyleRegion(htmlLanguageService, document.getText(), document.offsetAt(position))) {
|
||||||
|
return await next(document, position, context, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
const originalUri = document.uri.toString();
|
||||||
|
virtualDocumentContents.set(originalUri, getCSSVirtualContent(htmlLanguageService, document.getText()));
|
||||||
|
|
||||||
|
const vdocUriString = `embedded-content://css/${encodeURIComponent(
|
||||||
|
originalUri
|
||||||
|
)}.css`;
|
||||||
|
const vdocUri = Uri.parse(vdocUriString);
|
||||||
|
return await commands.executeCommand<CompletionList>(
|
||||||
|
'vscode.executeCompletionItemProvider',
|
||||||
|
vdocUri,
|
||||||
|
position,
|
||||||
|
context.triggerCharacter
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create the language client and start the client.
|
||||||
|
client = new LanguageClient(
|
||||||
|
'languageServerExample',
|
||||||
|
'Language Server Example',
|
||||||
|
serverOptions,
|
||||||
|
clientOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
// Start the client. This will also launch the server
|
||||||
|
client.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deactivate(): Thenable<void> | undefined {
|
||||||
|
if (!client) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return client.stop();
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es2019",
|
||||||
|
"lib": ["ES2019"],
|
||||||
|
"outDir": "out",
|
||||||
|
"rootDir": "src",
|
||||||
|
"sourceMap": true
|
||||||
|
},
|
||||||
|
"include": ["src"],
|
||||||
|
"exclude": ["node_modules", ".vscode-test"]
|
||||||
|
}
|
||||||
Generated
+1050
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"name": "dioxus-rsx-plugin",
|
||||||
|
"description": "Get HTML completion inside the html! macro for dioxus projects",
|
||||||
|
"author": "Jonathan Kelley",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/jkelleyrtp/dioxus"
|
||||||
|
},
|
||||||
|
"publisher": "jkelleyrtp",
|
||||||
|
"categories": [],
|
||||||
|
"keywords": [],
|
||||||
|
"engines": {
|
||||||
|
"vscode": "^1.43.0",
|
||||||
|
"node": "*"
|
||||||
|
},
|
||||||
|
"activationEvents": [
|
||||||
|
"onLanguage:html1"
|
||||||
|
],
|
||||||
|
"main": "./client/out/extension",
|
||||||
|
"contributes": {
|
||||||
|
"languages": [
|
||||||
|
{
|
||||||
|
"id": "rsx",
|
||||||
|
"extensions": [
|
||||||
|
".rs"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"grammars": [
|
||||||
|
{
|
||||||
|
"language": "rsx",
|
||||||
|
"scopeName": "text.rsx.basic",
|
||||||
|
"path": "./syntaxes/rsx.tmLanguage.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"vscode:prepublish": "cd client && npm install && cd .. && npm run compile",
|
||||||
|
"compile": "tsc -b",
|
||||||
|
"watch": "tsc -b -w",
|
||||||
|
"// postinstall": "cd client && npm install && cd ../server && npm install && cd ..",
|
||||||
|
"test": "sh ./scripts/e2e.sh"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/mocha": "^5.2.7",
|
||||||
|
"@types/node": "^12.12.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^3.0.2",
|
||||||
|
"@typescript-eslint/parser": "^3.0.2",
|
||||||
|
"eslint": "^7.1.0",
|
||||||
|
"typescript": "^4.0.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
//! Generate the syntax for the RSX language
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
"name": "lsp-sample-server",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"requires": true,
|
||||||
|
"dependencies": {
|
||||||
|
"vscode-html-languageservice": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-U+upM3gHp3HaF3wXAnUduA6IDKcz6frWS/dTAju3cZVIyZwOLBBFElQVlLH0ycHyMzqUFrjvdv+kEyPAEWfQ/g==",
|
||||||
|
"requires": {
|
||||||
|
"vscode-languageserver-types": "^3.15.0-next.2",
|
||||||
|
"vscode-nls": "^4.1.1",
|
||||||
|
"vscode-uri": "^2.0.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"vscode-languageserver-types": {
|
||||||
|
"version": "3.15.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz",
|
||||||
|
"integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ=="
|
||||||
|
},
|
||||||
|
"vscode-uri": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-eY9jmGoEnVf8VE8xr5znSah7Qt1P/xsCdErz+g8HYZtJ7bZqKH5E3d+6oVNm1AC/c6IHUDokbmVXKOi4qPAC9A=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"vscode-jsonrpc": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A=="
|
||||||
|
},
|
||||||
|
"vscode-languageserver": {
|
||||||
|
"version": "6.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-6.1.1.tgz",
|
||||||
|
"integrity": "sha512-DueEpkUAkD5XTR4MLYNr6bQIp/UFR0/IPApgXU3YfCBCB08u2sm9hRCs6DxYZELkk++STPjpcjksR2H8qI3cDQ==",
|
||||||
|
"requires": {
|
||||||
|
"vscode-languageserver-protocol": "^3.15.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"vscode-languageserver-protocol": {
|
||||||
|
"version": "3.15.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz",
|
||||||
|
"integrity": "sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw==",
|
||||||
|
"requires": {
|
||||||
|
"vscode-jsonrpc": "^5.0.1",
|
||||||
|
"vscode-languageserver-types": "3.15.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"vscode-languageserver-textdocument": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA=="
|
||||||
|
},
|
||||||
|
"vscode-languageserver-types": {
|
||||||
|
"version": "3.15.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz",
|
||||||
|
"integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ=="
|
||||||
|
},
|
||||||
|
"vscode-nls": {
|
||||||
|
"version": "4.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz",
|
||||||
|
"integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "lsp-sample-server",
|
||||||
|
"description": "Example implementation of a language server in node.",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"author": "Microsoft Corporation",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Microsoft/vscode-extension-samples"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"vscode-html-languageservice": "^3.0.3",
|
||||||
|
"vscode-languageserver": "^6.1.1",
|
||||||
|
"vscode-languageserver-textdocument": "^1.0.1"
|
||||||
|
},
|
||||||
|
"scripts": {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/* --------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
* ------------------------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
import { getLanguageService } from 'vscode-html-languageservice';
|
||||||
|
import { createConnection, InitializeParams, ProposedFeatures, TextDocuments, TextDocumentSyncKind } from 'vscode-languageserver';
|
||||||
|
import { TextDocument } from 'vscode-languageserver-textdocument';
|
||||||
|
|
||||||
|
// Create a connection for the server. The connection uses Node's IPC as a transport.
|
||||||
|
// Also include all preview / proposed LSP features.
|
||||||
|
let connection = createConnection(ProposedFeatures.all);
|
||||||
|
|
||||||
|
// Create a simple text document manager. The text document manager
|
||||||
|
// supports full document sync only
|
||||||
|
let documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);
|
||||||
|
|
||||||
|
const htmlLanguageService = getLanguageService();
|
||||||
|
|
||||||
|
connection.onInitialize((_params: InitializeParams) => {
|
||||||
|
return {
|
||||||
|
capabilities: {
|
||||||
|
textDocumentSync: TextDocumentSyncKind.Full,
|
||||||
|
// Tell the client that the server supports code completion
|
||||||
|
completionProvider: {
|
||||||
|
resolveProvider: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
connection.onInitialized(() => { });
|
||||||
|
|
||||||
|
connection.onCompletion(async (textDocumentPosition, token) => {
|
||||||
|
const document = documents.get(textDocumentPosition.textDocument.uri);
|
||||||
|
if (!document) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return htmlLanguageService.doComplete(
|
||||||
|
document,
|
||||||
|
textDocumentPosition.position,
|
||||||
|
htmlLanguageService.parseHTMLDocument(document)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
documents.listen(connection);
|
||||||
|
connection.listen();
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2019",
|
||||||
|
"lib": ["ES2019"],
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"sourceMap": true,
|
||||||
|
"strict": true,
|
||||||
|
"outDir": "out",
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
"include": ["src"],
|
||||||
|
"exclude": ["node_modules", ".vscode-test"]
|
||||||
|
}
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es2019",
|
||||||
|
"lib": [
|
||||||
|
"ES2019"
|
||||||
|
],
|
||||||
|
"outDir": "out",
|
||||||
|
"rootDir": "src",
|
||||||
|
"sourceMap": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
".vscode-test"
|
||||||
|
],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./client"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./server"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in new issue
Block a user