added vscode extensions

This commit is contained in:
tomit4 2021-11-05 11:26:45 -07:00
parent 7cde0829be
commit 26e2a50441
316 changed files with 37301 additions and 0 deletions

View file

@ -0,0 +1 @@
github: pranaygp

View file

@ -0,0 +1,3 @@
server/out
client/out
tests/out

View file

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata>
<Identity Language="en-US" Id="vscode-css-peek" Version="4.2.0" Publisher="pranaygp"/>
<DisplayName>CSS Peek</DisplayName>
<Description xml:space="preserve">Allow peeking to css ID and class strings as definitions from html files to respective CSS. Allows peek and goto definition.</Description>
<Tags>definition,css,scss,sass,less,peek,style,stylesheet,jump to stylesheet,multi-root ready</Tags>
<Categories></Categories>
<GalleryFlags>Public</GalleryFlags>
<Badges></Badges>
<Properties>
<Property Id="Microsoft.VisualStudio.Code.Engine" Value="^1.33.0" />
<Property Id="Microsoft.VisualStudio.Code.ExtensionDependencies" Value="" />
<Property Id="Microsoft.VisualStudio.Code.ExtensionPack" Value="" />
<Property Id="Microsoft.VisualStudio.Code.ExtensionKind" Value="workspace" />
<Property Id="Microsoft.VisualStudio.Code.LocalizedLanguages" Value="" />
<Property Id="Microsoft.VisualStudio.Services.Links.Source" Value="https://github.com/pranaygp/vscode-css-peek" />
<Property Id="Microsoft.VisualStudio.Services.Links.Getstarted" Value="https://github.com/pranaygp/vscode-css-peek" />
<Property Id="Microsoft.VisualStudio.Services.Links.GitHub" Value="https://github.com/pranaygp/vscode-css-peek" />
<Property Id="Microsoft.VisualStudio.Services.Links.Support" Value="https://github.com/pranaygp/vscode-css-peek/issues" />
<Property Id="Microsoft.VisualStudio.Services.Links.Learn" Value="https://github.com/pranaygp/vscode-css-peek/blob/master/README.md" />
<Property Id="Microsoft.VisualStudio.Services.GitHubFlavoredMarkdown" Value="true" />
</Properties>
<License>extension/LICENSE.txt</License>
<Icon>extension/css_peek_icon.png</Icon>
</Metadata>
<Installation>
<InstallationTarget Id="Microsoft.VisualStudio.Code"/>
</Installation>
<Dependencies/>
<Assets>
<Asset Type="Microsoft.VisualStudio.Code.Manifest" Path="extension/package.json" Addressable="true" />
<Asset Type="Microsoft.VisualStudio.Services.Content.Details" Path="extension/README.md" Addressable="true" /><Asset Type="Microsoft.VisualStudio.Services.Content.License" Path="extension/LICENSE.txt" Addressable="true" /><Asset Type="Microsoft.VisualStudio.Services.Icons.Default" Path="extension/css_peek_icon.png" Addressable="true" />
</Assets>
</PackageManifest>

View file

@ -0,0 +1,17 @@
Copyright (c) Pranay Prakash
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,132 @@
[![Build Status](https://travis-ci.org/pranaygp/vscode-css-peek.svg?branch=master)](https://travis-ci.org/pranaygp/vscode-css-peek)
[![Installs](https://vsmarketplacebadge.apphb.com/installs-short/pranaygp.vscode-css-peek.svg)](https://marketplace.visualstudio.com/items?itemName=pranaygp.vscode-css-peek)
[![Version](https://vsmarketplacebadge.apphb.com/version/pranaygp.vscode-css-peek.svg)](https://marketplace.visualstudio.com/items?itemName=pranaygp.vscode-css-peek)
[![Open VSX](https://img.shields.io/badge/Open%20VSX-vscode--css--peek-purple)](https://open-vsx.org/extension/pranaygp/vscode-css-peek)
[![codecov](https://codecov.io/gh/pranaygp/vscode-css-peek/branch/master/graph/badge.svg)](https://codecov.io/gh/pranaygp/vscode-css-peek)
## Backed By
> An amazing tool I've used before and they didn't ask me to say that :) - Extension Author
<p><a title="Try CodeStream" href="https://sponsorlink.codestream.com/?utm_source=vscmarket&amp;utm_campaign=pranaygp_css_peek&amp;utm_medium=banner"><img src="https://alt-images.codestream.com/codestream_logo_pranaygp_css_peek.png"></a></br>
Manage pull requests and conduct code reviews in your IDE with full source-tree context. Comment on any line, not just the diffs. Use jump-to-definition, your favorite keybindings, and code intelligence with more of your workflow.<br> <a title="Try CodeStream" href="https://sponsorlink.codestream.com/?utm_source=vscmarket&amp;utm_campaign=pranaygp_css_peek&amp;utm_medium=banner">Learn More</a></p>
# Functionality
This extension extends HTML and ejs code editing with `Go To Definition` and `Go To Symbol in Workspace` support for css/scss/less (classes and IDs) found in strings within the source code.
This was heavily inspired by a similar feature in [Brackets](http://brackets.io/) called CSS Inline Editors.
![working](https://github.com/pranaygp/vscode-css-peek/raw/master/readme/working.gif)
The extension supports all the normal capabilities of symbol definition tracking, but does it for css selectors (classes, IDs and HTML tags). This includes:
- Peek: load the css file inline and make quick edits right there. (`Ctrl+Shift+F12`)
- Go To: jump directly to the css file or open it in a new editor (`F12`)
- Hover: show the definition in a hover over the symbol (`Ctrl+hover`)
In addition, it supports the Symbol Provider so you can quickly jump to the right CSS/SCSS/LESS code if you already know the class or ID name
![Symbol Provider](https://github.com/pranaygp/vscode-css-peek/raw/master/readme/symbolProvider.gif)
## Configuration
- `cssPeek.supportTags` - Enable Peeking from HTML tags in addition to classnames and IDs. React components are ignored, but it's a good idea to disable this feature when using Angular.
- `cssPeek.peekFromLanguages` - A list of vscode language names where the extension should be used.
- `cssPeek.peekToExclude` - A list of file globs that filters out style files to not look for. By default, `node_modules` and `bower_components`
See editor docs for more details
- [Visual Studio Code: Goto Definition](https://code.visualstudio.com/docs/editor/editingevolved#_go-to-definition)
- [Visual Studio Code: Peek](https://code.visualstudio.com/docs/editor/editingevolved#_peek)
- [Visual Studio Code: Open Symbol By Name](https://code.visualstudio.com/Docs/editor/editingevolved#_open-symbol-by-name)
# Contributing
Contributions are greatly appreciated. Please fork the repository and submit a pull request.
# Changelog
> TODO: Keep the changelog upto date
## 4.2.0
- Support VSCode Workspace Trust [#107](https://github.com/pranaygp/vscode-css-peek/issues/107)
## 4.1.1
- Add CodeStream Banner
## 3.0.2
- Use Globs for configuration options instead of RegExp via [#61](https://github.com/pranaygp/vscode-css-peek/pull/61) ❤ [@arch-stack](https://github.com/arch-stack)
## 2.2.0
- Initial JSX support via [#49](https://github.com/pranaygp/vscode-css-peek/pull/49) ❤ [@ReiMcCl](https://github.com/ReiMcCl)
## 2.1.1
- (Temporarily) fix bug [#19](https://github.com/pranaygp/vscode-css-peek/issues/18) by handling errors from `findDocumentSymbols`
## 2.1.0
- Add support for Symbol Provider [#18](https://github.com/pranaygp/vscode-css-peek/issues/18)
> ![Symbol Provider](https://github.com/pranaygp/vscode-css-peek/raw/master/readme/symbolProvider.gif)
## 2.0.3
- Fix bug [#14](https://github.com/pranaygp/vscode-css-peek/issues/14) that caused CSS Peek to fail after any HTML comments
## 2.0.2
- Fix bug that limited the language support only to HTML. Now supports all languages provided by "activeLanguages" config
## 2.0.1
- Fix an error wherby the Overview was missing on the Visual Studio Marketplace
## 2.0.0
- A complete rewrite featuring the new [Language Server Protocol](https://github.com/Microsoft/language-server-protocol)
- Added scss support
- Added multi definition support (provides all CSS rules matching the selector)
- Added support for HTML tag selectors
## 1.3.3
- New Logo
## 1.3.0
- Add configuration option to ignore file from CSS lookup
## 1.2.4
- Crucial bug fix
## 1.2.3
- Workaround for bug if large number of files exist
## 1.2.2
- Better recognition of CSS selector word from cursor position
- Optimize code for fewer file lookups
## 1.2.1
- Fix README typo
## 1.2.0
- Add `less` support
- Configure search file extensions using "css_peek.searchFileExtensions"
## 1.1.0
- Update Icon
## 1.0.0
- Shamelessly copied code from [https://github.com/abierbaum/vscode-file-peek](https://github.com/abierbaum/vscode-file-peek)

View file

@ -0,0 +1,170 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deactivate = exports.activate = void 0;
const path = require("path");
const vscode_1 = require("vscode");
const vscode_languageclient_1 = require("vscode-languageclient");
const SUPPORTED_EXTENSIONS = ["css", "scss", "less"];
const SUPPORTED_EXTENSION_REGEX = /\.(css|scss|less)$/;
let defaultClient;
const clients = new Map();
let _sortedWorkspaceFolders;
function sortedWorkspaceFolders() {
if (_sortedWorkspaceFolders === void 0) {
_sortedWorkspaceFolders = vscode_1.workspace.workspaceFolders
? vscode_1.workspace.workspaceFolders
.map((folder) => {
let result = folder.uri.toString();
if (result.charAt(result.length - 1) !== "/") {
result = result + "/";
}
return result;
})
.sort((a, b) => {
return a.length - b.length;
})
: [];
}
return _sortedWorkspaceFolders;
}
vscode_1.workspace.onDidChangeWorkspaceFolders(() => (_sortedWorkspaceFolders = undefined));
function getOuterMostWorkspaceFolder(folder) {
const sorted = sortedWorkspaceFolders();
for (const element of sorted) {
let uri = folder.uri.toString();
if (uri.charAt(uri.length - 1) !== "/") {
uri = uri + "/";
}
if (uri.startsWith(element)) {
return vscode_1.workspace.getWorkspaceFolder(vscode_1.Uri.parse(element));
}
}
return folder;
}
function activate(context) {
const module = context.asAbsolutePath(path.join("server", "out", "server.js"));
const outputChannel = vscode_1.window.createOutputChannel("CSS Peek");
const config = vscode_1.workspace.getConfiguration("cssPeek");
const peekFromLanguages = config.get("peekFromLanguages");
const peekToInclude = SUPPORTED_EXTENSIONS.map((l) => `**/*.${l}`);
const peekToExclude = config.get("peekToExclude");
function didOpenTextDocument(document) {
// TODO: Return if unsupported document.languageId
if (!["file", "untitled"].includes(document.uri.scheme) ||
(!peekFromLanguages.includes(document.languageId) &&
!SUPPORTED_EXTENSION_REGEX.test(document.fileName))) {
return;
}
const documentSelector = [
...SUPPORTED_EXTENSIONS.map((language) => ({
scheme: "file",
language,
})),
...SUPPORTED_EXTENSIONS.map((language) => ({
scheme: "untitled",
language,
})),
...peekFromLanguages.map((language) => ({
scheme: "file",
language,
})),
...peekFromLanguages.map((language) => ({
scheme: "untitled",
language,
})),
];
const uri = document.uri;
// Untitled files go to a default client.
if (uri.scheme === "untitled" && !defaultClient) {
const debugOptions = { execArgv: ["--nolazy", "--inspect=6010"] };
const serverOptions = {
run: { module, transport: vscode_languageclient_1.TransportKind.ipc },
debug: { module, transport: vscode_languageclient_1.TransportKind.ipc, options: debugOptions },
};
const clientOptions = {
documentSelector,
synchronize: {
configurationSection: "cssPeek",
},
initializationOptions: {
stylesheets: [],
peekFromLanguages,
},
diagnosticCollectionName: "css-peek",
outputChannel,
};
defaultClient = new vscode_languageclient_1.LanguageClient("css-peek", "CSS Peek", serverOptions, clientOptions);
defaultClient.registerProposedFeatures();
defaultClient.start();
return;
}
let folder = vscode_1.workspace.getWorkspaceFolder(uri);
// Files outside a folder can't be handled. This might depend on the language.
// Single file languages like JSON might handle files outside the workspace folders.
if (!folder) {
return;
}
// If we have nested workspace folders we only start a server on the outer most workspace folder.
folder = getOuterMostWorkspaceFolder(folder);
if (!clients.has(folder.uri.toString())) {
vscode_1.workspace.findFiles(`{${(peekToInclude || []).join(",")}}`, `{${(peekToExclude || []).join(",")}}`).then((file_searches) => {
const potentialFiles = file_searches.filter((uri) => uri.scheme === "file");
const debugOptions = {
execArgv: ["--nolazy", `--inspect=${6011 + clients.size}`],
};
const serverOptions = {
run: { module, transport: vscode_languageclient_1.TransportKind.ipc },
debug: {
module,
transport: vscode_languageclient_1.TransportKind.ipc,
options: debugOptions,
},
};
const clientOptions = {
documentSelector,
diagnosticCollectionName: "css-peek",
synchronize: {
configurationSection: "cssPeek",
},
initializationOptions: {
stylesheets: potentialFiles.map((u) => ({
uri: u.toString(),
fsPath: u.fsPath,
})),
peekFromLanguages,
},
workspaceFolder: folder,
outputChannel,
};
const client = new vscode_languageclient_1.LanguageClient("css-peek", "CSS Peek", serverOptions, clientOptions);
client.registerProposedFeatures();
client.start();
clients.set(folder.uri.toString(), client);
});
}
}
vscode_1.workspace.onDidOpenTextDocument(didOpenTextDocument);
vscode_1.workspace.textDocuments.forEach(didOpenTextDocument);
vscode_1.workspace.onDidChangeWorkspaceFolders((event) => {
for (const folder of event.removed) {
const client = clients.get(folder.uri.toString());
if (client) {
clients.delete(folder.uri.toString());
client.stop();
}
}
});
}
exports.activate = activate;
function deactivate() {
const promises = [];
if (defaultClient) {
promises.push(defaultClient.stop());
}
for (const client of clients.values()) {
promises.push(client.stop());
}
return Promise.all(promises).then(() => undefined);
}
exports.deactivate = deactivate;
//# sourceMappingURL=extension.js.map

View file

@ -0,0 +1,20 @@
{
"name": "vscode-css-peek-client-part",
"description": "VSCode part of the language server",
"license": "MIT",
"author": "Pranay Prakash <pranay.gp@gmail.com>",
"repository": {
"type": "git",
"url": "https://github.com/pranaygp/vscode-css-peek.git"
},
"engines": {
"vscode": "^1.33.0"
},
"scripts": {},
"dependencies": {
"vscode-languageclient": "^5.2.1"
},
"devDependencies": {
"@types/vscode": "^1.33.0"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

View file

@ -0,0 +1,148 @@
{
"name": "vscode-css-peek",
"displayName": "CSS Peek",
"description": "Allow peeking to css ID and class strings as definitions from html files to respective CSS. Allows peek and goto definition.",
"author": "Pranay Prakash <pranay.gp@gmail.com>",
"icon": "css_peek_icon.png",
"license": "MIT",
"version": "4.2.0",
"repository": {
"type": "git",
"url": "https://github.com/pranaygp/vscode-css-peek"
},
"categories": [],
"keywords": [
"definition",
"css",
"scss",
"sass",
"less",
"peek",
"style",
"stylesheet",
"jump to stylesheet",
"multi-root ready"
],
"engines": {
"vscode": "^1.33.0"
},
"main": "./client/out/extension",
"publisher": "pranaygp",
"bugs": {
"url": "https://github.com/pranaygp/vscode-css-peek/issues"
},
"homepage": "https://github.com/pranaygp/vscode-css-peek/blob/master/README.md",
"activationEvents": [
"workspaceContains:**/*.css",
"workspaceContains:**/*.scss",
"workspaceContains:**/*.sass",
"workspaceContains:**/*.less"
],
"contributes": {
"configuration": {
"type": "object",
"title": "CSS Peek",
"properties": {
"cssPeek.enable": {
"scope": "window",
"type": "boolean",
"default": true,
"description": "Controls the enablement."
},
"cssPeek.supportTags": {
"scope": "window",
"type": "boolean",
"default": true,
"description": "Enable Peeking from HTML tags in addition to classnames and IDs. React components are ignored, but it's a good idea to disable this feature when using Angular"
},
"cssPeek.peekFromLanguages": {
"scope": "window",
"type": "array",
"default": [
"html",
"django-html",
"laravel-blade",
"razor",
"vue",
"blade",
"pug",
"jade",
"handlebars",
"php",
"twig",
"md",
"nunjucks",
"javascript",
"javascriptreact",
"erb",
"typescript",
"typescriptreact",
"HTML (Eex)",
"html-eex",
"ejs"
],
"items": {
"type": "string"
},
"description": "A list of vscode language names where the extension should be used."
},
"cssPeek.peekToExclude": {
"scope": "window",
"type": "array",
"default": [
"**/node_modules/**",
"**/bower_components/**"
],
"items": {
"type": "string"
},
"description": "A list of file globs that filters out peekable files"
},
"cssPeek.trace.server": {
"scope": "window",
"type": "string",
"enum": [
"off",
"messages",
"verbose"
],
"default": "off",
"description": "Traces the communication between VSCode and the language server."
}
}
}
},
"capabilities": {
"untrustedWorkspaces": {
"supported": true
}
},
"scripts": {
"vscode:prepublish": "yarn run compile",
"compile": "tsc -b",
"prettier": "prettier './{server,client,tests}/**/*' -c",
"lint": "yarn run eslint . --ext ts",
"watch": "tsc -b -w",
"test": "nyc node tests/out/runTest.js",
"posttest": "nyc report --reporter=json && codecov -f coverage/*.json",
"postinstall": "cd client && yarn && cd ../server && yarn && cd ../tests && yarn && cd .."
},
"devDependencies": {
"@types/mocha": "^8.0.0",
"@types/node": "^14.0.24",
"@typescript-eslint/eslint-plugin": "^3.7.0",
"@typescript-eslint/parser": "^3.7.0",
"codecov": "^3.7.2",
"eslint": "^7.5.0",
"mocha": "^8.3.2",
"nyc": "^15.1.0",
"prettier": "^2.0.5",
"typescript": "^3.9.7"
},
"__metadata": {
"id": "0b8f8d63-11a2-4194-969c-ca7488b3413a",
"publisherId": "3975bc66-f8bb-46a9-b8b6-430f013e4fa5",
"publisherDisplayName": "Pranay Prakash",
"installedTimestamp": 1632235242228
}
}

View file

@ -0,0 +1,85 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.findDefinition = exports.findSymbols = exports.getLanguageService = exports.isLanguageServiceSupported = void 0;
const path = require("path");
const vscode_css_languageservice_1 = require("vscode-css-languageservice");
const logger_1 = require("./../logger");
const languageServices = {
css: vscode_css_languageservice_1.getCSSLanguageService(),
scss: vscode_css_languageservice_1.getSCSSLanguageService(),
less: vscode_css_languageservice_1.getLESSLanguageService(),
};
function isLanguageServiceSupported(serviceId) {
return !!languageServices[serviceId];
}
exports.isLanguageServiceSupported = isLanguageServiceSupported;
function getLanguageService(document) {
let service = languageServices[document.languageId];
if (!service) {
logger_1.console.log("Document type is " + document.languageId + ", using css instead.");
service = languageServices["css"];
}
return service;
}
exports.getLanguageService = getLanguageService;
function getSelection(selector) {
switch (selector.attribute) {
case "id":
return "#" + selector.value;
case "class":
return "." + selector.value;
default:
return selector.value;
}
}
function resolveSymbolName(symbols, i) {
const name = symbols[i].name;
if (name.startsWith("&")) {
return resolveSymbolName(symbols, i - 1) + name.slice(1);
}
return name;
}
function findSymbols(selector, stylesheetMap) {
const foundSymbols = [];
// Construct RegExp of selector to test against the symbols
let selection = getSelection(selector);
const classOrIdSelector = selector.attribute === "class" || selector.attribute === "id";
if (selection[0] === ".") {
selection = "\\" + selection;
}
if (!classOrIdSelector) {
// Tag selectors must have nothing, whitespace, or a combinator before it.
selection = "(^|[\\s>+~])" + selection;
}
const re = new RegExp(selection + "(\\[[^\\]]*\\]|:{1,2}[\\w-()]+|\\.[\\w-]+|#[\\w-]+)*\\s*$", classOrIdSelector ? "" : "i");
// Test all the symbols against the RegExp
Object.keys(stylesheetMap).forEach((uri) => {
const { symbols } = stylesheetMap[uri];
try {
logger_1.console.log(`${path.basename(uri)} has ${symbols.length} symbols`);
symbols.forEach((symbol, i) => {
let name = resolveSymbolName(symbols, i);
logger_1.console.log(` ${symbol.location.range.start.line}:${symbol.location.range.start.character} ${symbol.deprecated ? "[deprecated] " : " "}${symbol.containerName ? `[container:${symbol.containerName}] ` : " "} [${symbol.kind}] ${name}`);
if (name.search(re) !== -1) {
foundSymbols.push(symbol);
}
else if (!classOrIdSelector) {
// Special case for tag selectors - match "*" as the rightmost character
if (/\*\s*$/.test(name)) {
foundSymbols.push(symbol);
}
}
});
}
catch (e) {
logger_1.console.log(e.stack);
}
});
return foundSymbols;
}
exports.findSymbols = findSymbols;
function findDefinition(selector, stylesheetMap) {
return findSymbols(selector, stylesheetMap).map(({ location }) => location);
}
exports.findDefinition = findDefinition;
//# sourceMappingURL=findDefinition.js.map

View file

@ -0,0 +1,114 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_html_languageservice_1 = require("vscode-html-languageservice");
const logger_1 = require("./../logger");
/**
* Find the selector given the document and the current cursor position.
* This is found by iterating forwards and backwards from the position to find a valid CSS class/id
*
* @param {vscode.TextDocument} document - The Document to check
* @param {vscode.Position} position - The current cursor position
* @returns {{attribute: string, value: string}} The valid CSS selector
*
* @memberOf PeekFileDefinitionProvider
*/
function findSelector(document, position, settings) {
const text = document.getText();
const offset = document.offsetAt(position);
let start = offset;
let end = offset;
// expand selection to this word specifically
while (start > 0 &&
text.charAt(start - 1) !== " " &&
text.charAt(start - 1) !== "'" &&
text.charAt(start - 1) !== '"' &&
text.charAt(start - 1) !== "\n" &&
text.charAt(start - 1) !== "/" &&
text.charAt(start - 1) !== "<")
start -= 1;
while (end < text.length &&
text.charAt(end) !== " " &&
text.charAt(end) !== "'" &&
text.charAt(end) !== '"' &&
text.charAt(end) !== "\n" &&
text.charAt(end) !== ">")
end += 1;
const selectorWord = text.slice(start, end);
let selector = null;
const htmlScanner = vscode_html_languageservice_1.getLanguageService().createScanner(text);
let attribute = null;
logger_1.console.log(`${selectorWord} ${start}`);
let tokenType = htmlScanner.scan();
while (tokenType !== vscode_html_languageservice_1.TokenType.EOS) {
switch (tokenType) {
case vscode_html_languageservice_1.TokenType.StartTag:
case vscode_html_languageservice_1.TokenType.EndTag:
attribute = null;
if (!settings.supportTags) {
break;
}
// FOR DEBUGGING
logger_1.console.log(` ${htmlScanner.getTokenText()} ${htmlScanner.getTokenOffset()} ${htmlScanner.getTokenEnd()}`);
const tokenOffset = htmlScanner.getTokenOffset();
if ([
"javascript",
"typescript",
"javascriptreact",
"typescriptreact",
].includes(document.languageId)) {
if (selectorWord[0].toUpperCase() === selectorWord[0]) {
// if the first letter is uppercase, this is a JSX component
break;
}
}
if (start === tokenOffset)
selector = { attribute: null, value: selectorWord };
break;
case vscode_html_languageservice_1.TokenType.AttributeName:
attribute = htmlScanner.getTokenText().toLowerCase();
// Convert the attribute to a standard class attribute
if (attribute === "classname") {
attribute = "class";
}
break;
case vscode_html_languageservice_1.TokenType.AttributeValue:
// FOR DEBUGGING
// console.log(
// `${htmlScanner.getTokenText()} ${htmlScanner.getTokenOffset()} ${htmlScanner.getTokenEnd()}`
// );
if (attribute === "class" || attribute === "id") {
const values = htmlScanner.getTokenText().slice(1, -1).split(" ");
// calculate startOffsets for each class/id in this attribute
// +1 because we sliced earlier, so the first offset is the offset + 1
let startOffset = htmlScanner.getTokenOffset() + 1;
const offsets = values.map((v) => {
const o = startOffset;
startOffset += v.length + 1; // add 1 for the space
return o;
});
values.forEach((value, i) => {
const startOffset = offsets[i];
// FOR DEBUGGING
// console.log(` ${value} ${startOffset}`);
if (start === startOffset) {
selector = { attribute, value };
}
});
}
break;
}
if (selector) {
break;
}
tokenType = htmlScanner.scan();
}
if (selector) {
logger_1.console.log(`${selector.value} is a "${selector.attribute || "html tag"}"`);
}
else {
logger_1.console.log("Invalid Selector");
}
return selector;
}
exports.default = findSelector;
//# sourceMappingURL=findSelector.js.map

View file

@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.create = exports.console = void 0;
exports.console = null;
function create(nConsole) {
exports.console = nConsole;
}
exports.create = create;
//# sourceMappingURL=index.js.map

View file

@ -0,0 +1,177 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const minimatch = require("minimatch");
const path = require("path");
const vscode_languageserver_1 = require("vscode-languageserver");
const findSelector_1 = require("./core/findSelector");
const findDefinition_1 = require("./core/findDefinition");
const logger_1 = require("./logger");
// Creates the LSP connection
const connection = vscode_languageserver_1.createConnection(vscode_languageserver_1.ProposedFeatures.all);
// Create a manager for open text documents
const documents = new vscode_languageserver_1.TextDocuments();
// Create a map of styleSheet URIs to the stylesheet text content
const styleSheets = {};
// The workspace folder this server is operating on
let workspaceFolder;
let hasConfigurationCapability = false;
let hasWorkspaceFolderCapability = false;
async function documentShouldBeIgnored(document) {
const settings = await getDocumentSettings(document.uri);
if (!settings.peekFromLanguages.includes(document.languageId) ||
settings.peekToExclude.find((glob) => minimatch(document.uri, glob))) {
return true;
}
else {
return false;
}
}
/* Handle Document Updates */
documents.onDidOpen(async (event) => {
if (await documentShouldBeIgnored(event.document)) {
return;
}
connection.console.log(`[Server(${process.pid}) ${path.basename(workspaceFolder)}/] Document opened: ${path.basename(event.document.uri)}`);
if (findDefinition_1.isLanguageServiceSupported(event.document.languageId)) {
const languageService = findDefinition_1.getLanguageService(event.document);
const stylesheet = languageService.parseStylesheet(event.document);
const symbols = languageService.findDocumentSymbols(event.document, stylesheet);
styleSheets[event.document.uri] = {
document: event.document,
symbols,
};
}
});
documents.onDidChangeContent(async (event) => {
if (await documentShouldBeIgnored(event.document)) {
return;
}
connection.console.log(`[Server(${process.pid}) ${path.basename(workspaceFolder)}/] Document changed: ${path.basename(event.document.uri)}`);
if (findDefinition_1.isLanguageServiceSupported(event.document.languageId)) {
const languageService = findDefinition_1.getLanguageService(event.document);
const stylesheet = languageService.parseStylesheet(event.document);
const symbols = languageService.findDocumentSymbols(event.document, stylesheet);
styleSheets[event.document.uri] = {
document: event.document,
symbols,
};
}
});
documents.listen(connection);
/* Server Initialization */
connection.onInitialize((params) => {
logger_1.create(connection.console);
const capabilities = params.capabilities;
workspaceFolder = params.rootUri;
// Does the client support the `workspace/configuration` request?
// If not, we will fall back using global settings
hasConfigurationCapability =
capabilities.workspace && !!capabilities.workspace.configuration;
hasWorkspaceFolderCapability =
capabilities.workspace && !!capabilities.workspace.workspaceFolders;
connection.console.log(`[Server(${process.pid}) ${path.basename(workspaceFolder)}/] onInitialize`);
setupInitialStyleMap(params);
connection.console.log(`[Server(${process.pid}) ${path.basename(workspaceFolder)}/] setupInitialStylemap`);
return {
capabilities: {
textDocumentSync: {
openClose: true,
change: vscode_languageserver_1.TextDocumentSyncKind.Full,
},
definitionProvider: true,
workspaceSymbolProvider: true,
},
};
});
connection.onInitialized(() => {
if (hasConfigurationCapability) {
// Register for all configuration changes.
connection.client.register(vscode_languageserver_1.DidChangeConfigurationNotification.type, undefined);
}
if (hasWorkspaceFolderCapability) {
connection.workspace.onDidChangeWorkspaceFolders((_event) => {
connection.console.log("Workspace folder change event received.");
});
}
});
// The global settings, used when the `workspace/configuration` request is not supported by the client.
const defaultSettings = {
supportTags: true,
peekFromLanguages: ["html"],
peekToExclude: ["**/node_modules/**", "**/bower_components/**"],
};
let globalSettings = defaultSettings;
// Cache the settings of all open documents
let documentSettings = new Map();
connection.onDidChangeConfiguration((change) => {
if (hasConfigurationCapability) {
// Reset all cached document settings
documentSettings.clear();
}
else {
globalSettings = (change.settings.cssPeek || defaultSettings);
}
});
function getDocumentSettings(resource) {
if (!hasConfigurationCapability) {
return Promise.resolve(globalSettings);
}
let result = documentSettings.get(resource);
if (!result) {
result = connection.workspace.getConfiguration({
scopeUri: resource,
section: "cssPeek",
});
documentSettings.set(resource, result);
}
return result;
}
// Only keep settings for open documents
documents.onDidClose((e) => {
documentSettings.delete(e.document.uri);
});
function setupInitialStyleMap(params) {
const styleFiles = params.initializationOptions.stylesheets;
styleFiles.forEach((fileUri) => {
const languageId = fileUri.fsPath.split(".").slice(-1)[0];
const text = fs.readFileSync(fileUri.fsPath, "utf8");
const document = vscode_languageserver_1.TextDocument.create(fileUri.uri, languageId, 1, text);
const languageService = findDefinition_1.getLanguageService(document);
const stylesheet = languageService.parseStylesheet(document);
const symbols = languageService.findDocumentSymbols(document, stylesheet);
styleSheets[fileUri.uri] = {
document,
symbols,
};
});
}
connection.onDefinition(async (textDocumentPositon) => {
const documentIdentifier = textDocumentPositon.textDocument;
const position = textDocumentPositon.position;
const document = documents.get(documentIdentifier.uri);
if (await documentShouldBeIgnored(document)) {
return null;
}
const settings = await getDocumentSettings(document.uri);
const selector = findSelector_1.default(document, position, settings);
if (!selector) {
return null;
}
return findDefinition_1.findDefinition(selector, styleSheets);
});
connection.onWorkspaceSymbol(({ query }) => {
const selectors = [
{
attribute: "class",
value: query,
},
{
attribute: "id",
value: query,
},
];
return selectors.reduce((p, selector) => [...p, ...findDefinition_1.findSymbols(selector, styleSheets)], []);
});
connection.listen();
//# sourceMappingURL=server.js.map

View file

@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function default_1(selector) {
switch (selector.attribute) {
case "id":
return "#" + selector.value;
case "class":
return "." + selector.value;
default:
return selector.value;
}
}
exports.default = default_1;
//# sourceMappingURL=selectorToString.js.map

View file

@ -0,0 +1,17 @@
{
"name": "vscode-css-peek",
"description": "CSS Peek Language Server",
"version": "0.0.1",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/pranaygp/vscode-css-peek"
},
"dependencies": {
"minimatch": "^3.0.4",
"vscode-css-languageservice": "^4.3.0",
"vscode-html-languageservice": "^3.1.0",
"vscode-languageserver": "^5.2.1"
},
"scripts": {}
}