🎉 initiate project *astro_rewrite*
This commit is contained in:
parent
ffd4d5e86c
commit
2ba37bfbe3
8658 changed files with 2268794 additions and 2538 deletions
190
node_modules/vscode-css-languageservice/lib/esm/services/cssFolding.js
generated
vendored
Normal file
190
node_modules/vscode-css-languageservice/lib/esm/services/cssFolding.js
generated
vendored
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
import { TokenType, Scanner } from '../parser/cssScanner';
|
||||
import { SCSSScanner, InterpolationFunction } from '../parser/scssScanner';
|
||||
import { LESSScanner } from '../parser/lessScanner';
|
||||
export function getFoldingRanges(document, context) {
|
||||
const ranges = computeFoldingRanges(document);
|
||||
return limitFoldingRanges(ranges, context);
|
||||
}
|
||||
function computeFoldingRanges(document) {
|
||||
function getStartLine(t) {
|
||||
return document.positionAt(t.offset).line;
|
||||
}
|
||||
function getEndLine(t) {
|
||||
return document.positionAt(t.offset + t.len).line;
|
||||
}
|
||||
function getScanner() {
|
||||
switch (document.languageId) {
|
||||
case 'scss':
|
||||
return new SCSSScanner();
|
||||
case 'less':
|
||||
return new LESSScanner();
|
||||
default:
|
||||
return new Scanner();
|
||||
}
|
||||
}
|
||||
function tokenToRange(t, kind) {
|
||||
const startLine = getStartLine(t);
|
||||
const endLine = getEndLine(t);
|
||||
if (startLine !== endLine) {
|
||||
return {
|
||||
startLine,
|
||||
endLine,
|
||||
kind
|
||||
};
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
const ranges = [];
|
||||
const delimiterStack = [];
|
||||
const scanner = getScanner();
|
||||
scanner.ignoreComment = false;
|
||||
scanner.setSource(document.getText());
|
||||
let token = scanner.scan();
|
||||
let prevToken = null;
|
||||
while (token.type !== TokenType.EOF) {
|
||||
switch (token.type) {
|
||||
case TokenType.CurlyL:
|
||||
case InterpolationFunction:
|
||||
{
|
||||
delimiterStack.push({ line: getStartLine(token), type: 'brace', isStart: true });
|
||||
break;
|
||||
}
|
||||
case TokenType.CurlyR: {
|
||||
if (delimiterStack.length !== 0) {
|
||||
const prevDelimiter = popPrevStartDelimiterOfType(delimiterStack, 'brace');
|
||||
if (!prevDelimiter) {
|
||||
break;
|
||||
}
|
||||
let endLine = getEndLine(token);
|
||||
if (prevDelimiter.type === 'brace') {
|
||||
/**
|
||||
* Other than the case when curly brace is not on a new line by itself, for example
|
||||
* .foo {
|
||||
* color: red; }
|
||||
* Use endLine minus one to show ending curly brace
|
||||
*/
|
||||
if (prevToken && getEndLine(prevToken) !== endLine) {
|
||||
endLine--;
|
||||
}
|
||||
if (prevDelimiter.line !== endLine) {
|
||||
ranges.push({
|
||||
startLine: prevDelimiter.line,
|
||||
endLine,
|
||||
kind: undefined
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
/**
|
||||
* In CSS, there is no single line comment prefixed with //
|
||||
* All comments are marked as `Comment`
|
||||
*/
|
||||
case TokenType.Comment: {
|
||||
const commentRegionMarkerToDelimiter = (marker) => {
|
||||
if (marker === '#region') {
|
||||
return { line: getStartLine(token), type: 'comment', isStart: true };
|
||||
}
|
||||
else {
|
||||
return { line: getEndLine(token), type: 'comment', isStart: false };
|
||||
}
|
||||
};
|
||||
const getCurrDelimiter = (token) => {
|
||||
const matches = token.text.match(/^\s*\/\*\s*(#region|#endregion)\b\s*(.*?)\s*\*\//);
|
||||
if (matches) {
|
||||
return commentRegionMarkerToDelimiter(matches[1]);
|
||||
}
|
||||
else if (document.languageId === 'scss' || document.languageId === 'less') {
|
||||
const matches = token.text.match(/^\s*\/\/\s*(#region|#endregion)\b\s*(.*?)\s*/);
|
||||
if (matches) {
|
||||
return commentRegionMarkerToDelimiter(matches[1]);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const currDelimiter = getCurrDelimiter(token);
|
||||
// /* */ comment region folding
|
||||
// All #region and #endregion cases
|
||||
if (currDelimiter) {
|
||||
if (currDelimiter.isStart) {
|
||||
delimiterStack.push(currDelimiter);
|
||||
}
|
||||
else {
|
||||
const prevDelimiter = popPrevStartDelimiterOfType(delimiterStack, 'comment');
|
||||
if (!prevDelimiter) {
|
||||
break;
|
||||
}
|
||||
if (prevDelimiter.type === 'comment') {
|
||||
if (prevDelimiter.line !== currDelimiter.line) {
|
||||
ranges.push({
|
||||
startLine: prevDelimiter.line,
|
||||
endLine: currDelimiter.line,
|
||||
kind: 'region'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Multiline comment case
|
||||
else {
|
||||
const range = tokenToRange(token, 'comment');
|
||||
if (range) {
|
||||
ranges.push(range);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
prevToken = token;
|
||||
token = scanner.scan();
|
||||
}
|
||||
return ranges;
|
||||
}
|
||||
function popPrevStartDelimiterOfType(stack, type) {
|
||||
if (stack.length === 0) {
|
||||
return null;
|
||||
}
|
||||
for (let i = stack.length - 1; i >= 0; i--) {
|
||||
if (stack[i].type === type && stack[i].isStart) {
|
||||
return stack.splice(i, 1)[0];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* - Sort regions
|
||||
* - Remove invalid regions (intersections)
|
||||
* - If limit exceeds, only return `rangeLimit` amount of ranges
|
||||
*/
|
||||
function limitFoldingRanges(ranges, context) {
|
||||
const maxRanges = context && context.rangeLimit || Number.MAX_VALUE;
|
||||
const sortedRanges = ranges.sort((r1, r2) => {
|
||||
let diff = r1.startLine - r2.startLine;
|
||||
if (diff === 0) {
|
||||
diff = r1.endLine - r2.endLine;
|
||||
}
|
||||
return diff;
|
||||
});
|
||||
const validRanges = [];
|
||||
let prevEndLine = -1;
|
||||
sortedRanges.forEach(r => {
|
||||
if (!(r.startLine < prevEndLine && prevEndLine < r.endLine)) {
|
||||
validRanges.push(r);
|
||||
prevEndLine = r.endLine;
|
||||
}
|
||||
});
|
||||
if (validRanges.length < maxRanges) {
|
||||
return validRanges;
|
||||
}
|
||||
else {
|
||||
return validRanges.slice(0, maxRanges);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue