mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] owl-vision: syntax scripts, single quotes attributes and slot props highlight and switch below command
This commit adds the following: - Syntax builder scripts to make syntaxes easier to read and edit - Syntax highlight in single quote attributes - Syntax highlight for slot props - Basic syntax highlight for xpaths - Added `Switch Below` command This commit fixes the following: - Using `Switch Besides` or `Switch Below` does not open a new panel if one was already open - Fixed missing space in component's snippet indentation
This commit is contained in:
committed by
Géry Debongnie
parent
398df543fe
commit
34489a2494
@@ -0,0 +1,48 @@
|
||||
import { createTagPattern, exportPatterns } from "./syntax_builder_utils.mjs";
|
||||
import {
|
||||
htmlAttributes,
|
||||
owlAttributesDynamic,
|
||||
owlAttributesFormattedString,
|
||||
owlAttributesStatic,
|
||||
propsAttributes
|
||||
} from "./syntax_parts/owl_attributes.mjs";
|
||||
import { xpathAttributes } from "./syntax_parts/xpath.mjs";
|
||||
|
||||
const componentsTags = createTagPattern("component-tags", {
|
||||
match: "[A-Z][a-zA-Z0-9_]*",
|
||||
name: "entity.name.type.class owl.component",
|
||||
patterns: [
|
||||
owlAttributesDynamic,
|
||||
owlAttributesDynamic,
|
||||
propsAttributes,
|
||||
],
|
||||
});
|
||||
|
||||
const htmlTags = createTagPattern("html-tags", {
|
||||
match: "[a-z][a-zA-Z0-9_:.]+|[abiqsuw]",
|
||||
name: "entity.name.tag.localname.xml owl.xml.tag",
|
||||
patterns: [
|
||||
owlAttributesFormattedString,
|
||||
xpathAttributes,
|
||||
owlAttributesDynamic,
|
||||
owlAttributesStatic,
|
||||
htmlAttributes,
|
||||
],
|
||||
});
|
||||
|
||||
const tTag = createTagPattern("t-tag", {
|
||||
match: "t(?![a-zA-Z])",
|
||||
name: "entity.name.tag.localname.xml owl.tag",
|
||||
patterns: [
|
||||
propsAttributes,
|
||||
owlAttributesFormattedString,
|
||||
owlAttributesDynamic,
|
||||
owlAttributesStatic,
|
||||
],
|
||||
});
|
||||
|
||||
exportPatterns(
|
||||
"L:text.xml -comment",
|
||||
"owl.template",
|
||||
[componentsTags, htmlTags, tTag]
|
||||
);
|
||||
@@ -0,0 +1,117 @@
|
||||
import { writeFileSync } from "fs";
|
||||
import { dirname, resolve } from "path";
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const REPOSITORY = {};
|
||||
|
||||
export function exportPatterns(injectionSelector, scopeName, patterns) {
|
||||
const data = {
|
||||
injectionSelector: injectionSelector,
|
||||
scopeName: scopeName,
|
||||
patterns: [],
|
||||
repository: {}
|
||||
}
|
||||
|
||||
for (const pattern of patterns) {
|
||||
data.patterns.push({ include: `#${pattern.id}` });
|
||||
}
|
||||
|
||||
for (const id in REPOSITORY) {
|
||||
const pattern = { ...REPOSITORY[id] };
|
||||
|
||||
delete pattern.id;
|
||||
|
||||
data.repository[id] = pattern;
|
||||
}
|
||||
|
||||
const currentDir = dirname(fileURLToPath(import.meta.url));
|
||||
const filePath = resolve(currentDir, "../syntaxes", `${scopeName}.json`);
|
||||
writeFileSync(filePath, JSON.stringify(data, null, 4));
|
||||
console.info(`Sucessfuly build ./syntaxes/${scopeName}.json`);
|
||||
}
|
||||
|
||||
export function createPattern(id, { name, match, begin, end, contentName, beginCaptures, endCaptures, patterns }) {
|
||||
const pattern = { ...arguments[1] };
|
||||
if (id) {
|
||||
pattern.id = id;
|
||||
REPOSITORY[id] = pattern;
|
||||
}
|
||||
|
||||
function mapCaptures(name, captures) {
|
||||
if (!captures) {
|
||||
return;
|
||||
}
|
||||
|
||||
pattern[name] = {};
|
||||
for (const key in captures) {
|
||||
pattern[name][key] = { name: captures[key] }
|
||||
}
|
||||
}
|
||||
|
||||
mapCaptures("beginCaptures", beginCaptures);
|
||||
mapCaptures("endCaptures", endCaptures);
|
||||
|
||||
pattern.patterns = [];
|
||||
|
||||
if (patterns) {
|
||||
for (const childPattern of patterns) {
|
||||
if (typeof childPattern === "string") {
|
||||
pattern.patterns.push({ include: childPattern });
|
||||
} else if (childPattern.id) {
|
||||
pattern.patterns.push({ include: `#${childPattern.id}` });
|
||||
} else {
|
||||
pattern.patterns.push(childPattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pattern;
|
||||
}
|
||||
|
||||
export function createTagPattern(id, { match, name, patterns }) {
|
||||
return createPattern(id, {
|
||||
begin: `(</?)(${match})`,
|
||||
beginCaptures: {
|
||||
"1": "punctuation.definition.tag.xml owl.xml.punctuation",
|
||||
"2": name,
|
||||
},
|
||||
end: "\\s*([/?]?>)",
|
||||
endCaptures: {
|
||||
"1": "punctuation.definition.tag.xml punctuation",
|
||||
},
|
||||
patterns,
|
||||
});
|
||||
}
|
||||
|
||||
export function createAttributePatterns(id, { match, attributeName, contentName = "", patterns = [] }) {
|
||||
return createPattern(id, {
|
||||
patterns: [
|
||||
createPattern(undefined, {
|
||||
contentName: contentName !== null ? (contentName + " string.quoted.double.xml").trim() : undefined,
|
||||
begin: `(\\s*)(${match})(=)(")`,
|
||||
beginCaptures: {
|
||||
"2": "entity.other.attribute-name.localname.xml " + attributeName,
|
||||
"4": "punctuation.definition.string.begin.xml",
|
||||
},
|
||||
end: `(")`,
|
||||
endCaptures: {
|
||||
"0": "punctuation.definition.string.end.xml",
|
||||
},
|
||||
patterns,
|
||||
}),
|
||||
createPattern(undefined, {
|
||||
contentName: contentName !== null ? (contentName + " string.quoted.single.xml").trim() : undefined,
|
||||
begin: `(\\s*)(${match})(=)(')`,
|
||||
beginCaptures: {
|
||||
"2": "entity.other.attribute-name.localname.xml " + attributeName,
|
||||
"4": "punctuation.definition.string.begin.xml",
|
||||
},
|
||||
end: `(')`,
|
||||
endCaptures: {
|
||||
"0": "punctuation.definition.string.end.xml",
|
||||
},
|
||||
patterns,
|
||||
})
|
||||
]
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
import { createAttributePatterns, createPattern } from "../syntax_builder_utils.mjs";
|
||||
|
||||
export const inilineJs = [createPattern("inline-js", {
|
||||
patterns: [
|
||||
{
|
||||
match: "\\s(=>)\\s",
|
||||
captures: {
|
||||
"1": {
|
||||
name: "string.quoted.double.xml owl.arrow",
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
match: "\\b(props)\\b",
|
||||
captures: {
|
||||
"1": {
|
||||
name: "variable.language.js owl.expression.props",
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
match: "\\s(and|or)\\s",
|
||||
captures: {
|
||||
"1": {
|
||||
name: "keyword.operator.logical.js owl.logical",
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
include: "source.js"
|
||||
}
|
||||
]
|
||||
})];
|
||||
|
||||
const formattedString = createPattern("formatted-string", {
|
||||
contentName: "meta.embedded.block.javascript",
|
||||
begin: `({{)`,
|
||||
beginCaptures: {
|
||||
"1": "owl.double-curlybrackets",
|
||||
},
|
||||
end: `(}})`,
|
||||
endCaptures: {
|
||||
"1": "owl.double-curlybrackets",
|
||||
},
|
||||
patterns: inilineJs
|
||||
});
|
||||
|
||||
// -------------------------------- Attributes --------------------------------
|
||||
|
||||
export const htmlAttributes = createAttributePatterns("html-attributes", {
|
||||
match: "[a-z]{2}[a-z_:.-]+",
|
||||
attributeName: "owl.xml.attribute",
|
||||
});
|
||||
|
||||
export const propsAttributes = createAttributePatterns("props-attributes", {
|
||||
match: "[a-zA-Z]{2}[a-zA-Z_:.]*",
|
||||
contentName: "meta.embedded.block.javascript",
|
||||
attributeName: "owl.attribute owl.attribute.props",
|
||||
patterns: inilineJs,
|
||||
});
|
||||
|
||||
export const owlAttributesDynamic = createAttributePatterns("owl-attributes-dynamic", {
|
||||
match: [
|
||||
"t-if",
|
||||
"t-else",
|
||||
"t-elif",
|
||||
"t-foreach",
|
||||
"t-as",
|
||||
"t-key",
|
||||
"t-esc",
|
||||
"t-out",
|
||||
"t-props",
|
||||
"t-component",
|
||||
"t-set",
|
||||
"t-value",
|
||||
"t-portal",
|
||||
"t-slot-scope",
|
||||
"t-att-[a-z_:.-]+",
|
||||
"t-on-[a-z_:.-]+"
|
||||
].join("|"),
|
||||
contentName: "meta.embedded.block.javascript",
|
||||
attributeName: "owl.attribute owl.attribute.dynamic",
|
||||
patterns: inilineJs,
|
||||
});
|
||||
|
||||
export const owlAttributesStatic = createAttributePatterns("owl-attributes-static", {
|
||||
match: [
|
||||
"t-name",
|
||||
"t-ref",
|
||||
"t-set-slot",
|
||||
"t-model",
|
||||
"t-inherit",
|
||||
"t-inherit-mode",
|
||||
"t-translation"
|
||||
].join("|"),
|
||||
attributeName: "owl.attribute owl.attribute.static",
|
||||
});
|
||||
|
||||
export const owlAttributesFormattedString = createAttributePatterns("owl-attributes-formatted-string", {
|
||||
match: ["t-call", "t-slot", "t-attf-[a-z_:.-]+"].join("|"),
|
||||
attributeName: "owl.attribute owl.attribute.formatted",
|
||||
patterns: [formattedString],
|
||||
});
|
||||
@@ -0,0 +1,105 @@
|
||||
import { createAttributePatterns, createPattern } from "../syntax_builder_utils.mjs";
|
||||
|
||||
const xpathPattern = [createPattern("xpath", {
|
||||
patterns: [
|
||||
{
|
||||
begin: "\\[",
|
||||
beginCaptures: {
|
||||
"0": {
|
||||
name: "punctuation.definition",
|
||||
}
|
||||
},
|
||||
end: "\\]",
|
||||
endCaptures: {
|
||||
"0": {
|
||||
name: "punctuation.definition",
|
||||
}
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
begin: "'",
|
||||
beginCaptures: {
|
||||
"0": {
|
||||
name: "punctuation.definition",
|
||||
}
|
||||
},
|
||||
end: "'",
|
||||
endCaptures: {
|
||||
"0": {
|
||||
name: "punctuation.definition",
|
||||
}
|
||||
},
|
||||
contentName: "string.quoted.single",
|
||||
},
|
||||
{
|
||||
begin: "\\\"",
|
||||
beginCaptures: {
|
||||
"0": {
|
||||
name: "punctuation.definition",
|
||||
}
|
||||
},
|
||||
end: "\\\"",
|
||||
endCaptures: {
|
||||
"0": {
|
||||
name: "punctuation.definition",
|
||||
}
|
||||
},
|
||||
contentName: "string.quoted.double",
|
||||
},
|
||||
{
|
||||
match: "(@)([a-zA-Z0-9_:\\-]+)\\b",
|
||||
captures: {
|
||||
"1": {
|
||||
name: "punctuation.definition",
|
||||
},
|
||||
"2": {
|
||||
name: "entity.other.attribute-name",
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
match: "(\\(|\\))",
|
||||
name: "meta.brace.round",
|
||||
},
|
||||
{
|
||||
match: "[0-9]+(\\.[0-9]+)?",
|
||||
name: "constant.numeric.decimal",
|
||||
},
|
||||
{
|
||||
match: "\\b(hasclass)\\b",
|
||||
captures: {
|
||||
"1": {
|
||||
name: "entity.name.function",
|
||||
},
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
match: "/{1,2}",
|
||||
name: "text",
|
||||
},
|
||||
{
|
||||
match: "(?<!@)([A-Z][a-zA-Z]+)\\b",
|
||||
captures: {
|
||||
"1": {
|
||||
name: "entity.name.type.class",
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
match: "(?<!@)([a-z][a-zA-Z0-9_:.]+|[abiqsuw])\\b",
|
||||
captures: {
|
||||
"1": {
|
||||
name: "entity.name.tag",
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
})];
|
||||
|
||||
export const xpathAttributes = createAttributePatterns("xpath-attributes", {
|
||||
match: "expr",
|
||||
attributeName: "owl.xml.attribute owl.xml.attribute.xpath",
|
||||
patterns: xpathPattern,
|
||||
});
|
||||
Reference in New Issue
Block a user