дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 11:15:40 +02:00
fix(editor): align Python identifier colors and unused-parameter styling (#1572)
CI / Changes (push) Successful in 2s
Language smoke / Language smoke (kotlin) (push) Failing after 5s
Language smoke / Language smoke (go) (push) Failing after 7s
Language smoke / Language smoke (java) (push) Failing after 6s
Language smoke / Language smoke (python) (push) Failing after 4s
Language smoke / Language smoke (rust) (push) Failing after 5s
Language smoke / Language smoke (typescript) (push) Failing after 4s
CI / Plugins (SDK, official, fixtures) (push) Successful in 3m8s
CI / Cargo deny (push) Successful in 56s
CI / Remote server (linux musl) (push) Successful in 5m57s
CI / E2E (push) Failing after 15m56s
CI / Frontend (push) Failing after 24m3s
CI / Rust (ubuntu-22.04) (push) Failing after 46m51s
CI / Rust (macos-latest) (push) Canceled after 0s
CI / Rust (windows-latest) (push) Canceled after 0s
CI / Changes (push) Successful in 2s
Language smoke / Language smoke (kotlin) (push) Failing after 5s
Language smoke / Language smoke (go) (push) Failing after 7s
Language smoke / Language smoke (java) (push) Failing after 6s
Language smoke / Language smoke (python) (push) Failing after 4s
Language smoke / Language smoke (rust) (push) Failing after 5s
Language smoke / Language smoke (typescript) (push) Failing after 4s
CI / Plugins (SDK, official, fixtures) (push) Successful in 3m8s
CI / Cargo deny (push) Successful in 56s
CI / Remote server (linux musl) (push) Successful in 5m57s
CI / E2E (push) Failing after 15m56s
CI / Frontend (push) Failing after 24m3s
CI / Rust (ubuntu-22.04) (push) Failing after 46m51s
CI / Rust (macos-latest) (push) Canceled after 0s
CI / Rust (windows-latest) (push) Canceled after 0s
Python defaults diverged in several places: built-ins used the predefined magenta, __init__/__doc__ used function/self colours, instance fields the property colour, f-strings and byte strings the generic string colour, and the PEP 695 type keyword was uncoloured. Python now has its own tokens for built-ins, predefined definitions/usages, f-strings and byte strings; instance fields follow identifiers; type is a keyword. Unused parameters (not reported by Pyrefly) are greyed by a scope-aware local check that skips self/cls/_ names and signatures dictated elsewhere: stubs, @abstractmethod/@overload/@override, dunder methods and methods of classes with bases. Co-authored-by: muutot <[email protected]> Co-Authored-By: Claude Opus 5.5 <[email protected]>
Цей коміт міститься в:
14 files changed
+239
-15
No files matched your search
@@ -50,6 +50,71 @@ class Foo:
|
||||
);
|
||||
});
|
||||
|
||||
it("marks unused parameters and highlights type and f-string keywords", async () => {
|
||||
const state = await parse(`type Alias = list[int]
|
||||
s = f"value={1}"
|
||||
def used(x):
|
||||
return x
|
||||
def unused(param):
|
||||
return 1
|
||||
def skipped(self, _hidden):
|
||||
return 1
|
||||
`);
|
||||
const tree = syntaxTree(state);
|
||||
const kinds = pythonSymbolKinds(tree, state.doc);
|
||||
const kindOf = (name: string) =>
|
||||
[...kinds]
|
||||
.filter(([range]) => {
|
||||
const [from, to] = range.split(":").map(Number);
|
||||
return state.doc.sliceString(from!, to!) === name;
|
||||
})
|
||||
.map(([, kind]) => kind);
|
||||
expect(kindOf("param")).toEqual(["unusedParameter"]);
|
||||
expect(kindOf("x")).toEqual(["parameter", "parameter"]);
|
||||
expect(kindOf("self")).toEqual(["parameter"]);
|
||||
expect(kindOf("_hidden")).toEqual(["parameter"]);
|
||||
|
||||
// Signatures dictated elsewhere: stubs, abstract / overloaded methods, dunders, overrides.
|
||||
const stubs = await parse(`from abc import abstractmethod
|
||||
class Plain:
|
||||
def method(self, unused_a):
|
||||
return 1
|
||||
def stub(self, stub_a):
|
||||
"""Doc."""
|
||||
...
|
||||
def todo(self, todo_a):
|
||||
raise NotImplementedError
|
||||
def nothing(self, pass_a): pass
|
||||
@abstractmethod
|
||||
def abstract(self, abstract_a):
|
||||
return 1
|
||||
def __exit__(self, exc_type, exc, tb):
|
||||
return None
|
||||
class Child(Plain):
|
||||
def method(self, override_a):
|
||||
return 2
|
||||
`);
|
||||
const stubKinds = pythonSymbolKinds(syntaxTree(stubs), stubs.doc);
|
||||
const stubKindOf = (name: string) =>
|
||||
[...stubKinds]
|
||||
.filter(([range]) => {
|
||||
const [from, to] = range.split(":").map(Number);
|
||||
return stubs.doc.sliceString(from!, to!) === name;
|
||||
})
|
||||
.map(([, kind]) => kind);
|
||||
expect(stubKindOf("unused_a")).toEqual(["unusedParameter"]);
|
||||
for (const name of ["stub_a", "todo_a", "pass_a", "abstract_a", "exc_type", "tb", "override_a"])
|
||||
expect(stubKindOf(name), name).toEqual(["parameter"]);
|
||||
|
||||
const ranges = pythonSyntaxRanges(tree, state.doc, kinds);
|
||||
const styles = ranges.map((r) => [state.doc.sliceString(r.from, r.to), r.className]);
|
||||
expect(styles).toContainEqual(["param", "cm-sem-parameter cm-sem-unused"]);
|
||||
expect(styles).toContainEqual(["type", "cm-sem-keyword"]);
|
||||
const fstring = ranges.filter((r) => r.className === "cm-sem-python-fstring");
|
||||
expect(fstring.length).toBeGreaterThan(0);
|
||||
expect(fstring.some((r) => state.doc.sliceString(r.from, r.to).includes("value="))).toBe(true);
|
||||
});
|
||||
|
||||
it("lets server classification override the local builtin guess", async () => {
|
||||
const state = await parse("print(1)");
|
||||
const ranges = semanticRanges(
|
||||
|
||||
@@ -19,6 +19,7 @@ export type PythonSymbolKind =
|
||||
| "constant"
|
||||
| "property"
|
||||
| "typeParameter"
|
||||
| "unusedParameter"
|
||||
| "builtin";
|
||||
|
||||
const PYTHON_CLASSES: Record<PythonSymbolKind, string> = {
|
||||
@@ -32,6 +33,7 @@ const PYTHON_CLASSES: Record<PythonSymbolKind, string> = {
|
||||
constant: "cm-sem-constant cm-sem-python-constant",
|
||||
property: "cm-sem-property cm-sem-python-property",
|
||||
typeParameter: "cm-sem-typeParameter cm-sem-python-type-parameter",
|
||||
unusedParameter: "cm-sem-parameter cm-sem-unused",
|
||||
builtin: "cm-sem-builtin cm-sem-python-builtin",
|
||||
};
|
||||
|
||||
@@ -91,6 +93,7 @@ const KIND_PRIORITY: Record<PythonSymbolKind, number> = {
|
||||
globalVariable: 70,
|
||||
typeParameter: 90,
|
||||
parameter: 80,
|
||||
unusedParameter: 80,
|
||||
property: 80,
|
||||
constant: 70,
|
||||
classAttribute: 60,
|
||||
@@ -106,6 +109,33 @@ function scope(node: SyntaxNode | null): SyntaxNode | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
const STUB_STATEMENTS = new Set(["PassStatement", "RaiseStatement"]);
|
||||
|
||||
/**
|
||||
* Whether the parameters `fn` doesn't read count as unused. Not for stubs (a body of only a
|
||||
* docstring, `...`, `pass` or `raise`), `@abstractmethod` / `@overload` / `@override`, dunder
|
||||
* methods or methods of a class with bases: those signatures are dictated elsewhere.
|
||||
*/
|
||||
function checksUnusedParameters(fn: SyntaxNode, doc: Text): boolean {
|
||||
if (fn.name !== "FunctionDefinition") return true;
|
||||
const name = directName(fn);
|
||||
if (name && /^__\w+__$/.test(doc.sliceString(name.from, name.to))) return false;
|
||||
if (fn.parent?.name === "DecoratedStatement")
|
||||
for (let d = fn.parent.firstChild; d; d = d.nextSibling)
|
||||
if (d.name === "Decorator" && /\b(?:abstractmethod|overload|override)\b/.test(doc.sliceString(d.from, d.to)))
|
||||
return false;
|
||||
const owner = scope(fn.parent);
|
||||
if (owner?.name === "ClassDefinition" && owner.getChild("ArgList")) return false;
|
||||
const body = fn.getChild("Body");
|
||||
for (let st = body?.firstChild; st; st = st.nextSibling) {
|
||||
if (st.name === ":" || st.name === "Comment" || STUB_STATEMENTS.has(st.name)) continue;
|
||||
const only = st.name === "ExpressionStatement" ? st.firstChild : null;
|
||||
if (only && !only.nextSibling && (only.name === "String" || only.name === "Ellipsis")) continue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function enclosingClass(node: SyntaxNode | null): SyntaxNode | null {
|
||||
for (; node; node = node.parent) if (node.name === "ClassDefinition") return node;
|
||||
return null;
|
||||
@@ -340,6 +370,24 @@ export function pythonSymbolKinds(tree: Tree, doc: Text): Map<string, PythonSymb
|
||||
},
|
||||
});
|
||||
|
||||
const usedParameters = new Set<string>();
|
||||
tree.iterate({
|
||||
enter(cursor) {
|
||||
const node = cursor.node;
|
||||
if (node.name !== "VariableName" || hasAncestor(node, "ParamList")) return;
|
||||
const name = text(node);
|
||||
let crossedFunction = false;
|
||||
for (let current = scope(node); current; current = scope(current.parent)) {
|
||||
if (FUNCTION_SCOPES.has(current.name)) crossedFunction = true;
|
||||
const kind = bindings.get(key(current))?.get(name);
|
||||
if (!kind) continue;
|
||||
if (crossedFunction && current.name === "ClassDefinition" && kind !== "typeParameter") continue;
|
||||
if (kind === "parameter") usedParameters.add(`${key(current)}:${name}`);
|
||||
break;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const resolve = (
|
||||
node: SyntaxNode,
|
||||
name: string,
|
||||
@@ -394,6 +442,18 @@ export function pythonSymbolKinds(tree: Tree, doc: Text): Map<string, PythonSymb
|
||||
const kindFor = (node: SyntaxNode): PythonSymbolKind | undefined => {
|
||||
const name = text(node);
|
||||
if (node.name === "PropertyName") return memberKind(node, name);
|
||||
if (node.parent?.name === "ParamList") {
|
||||
const owner = scope(node);
|
||||
if (
|
||||
owner &&
|
||||
name !== "self" &&
|
||||
name !== "cls" &&
|
||||
!name.startsWith("_") &&
|
||||
!usedParameters.has(`${key(owner)}:${name}`) &&
|
||||
checksUnusedParameters(owner, doc)
|
||||
)
|
||||
return "unusedParameter";
|
||||
}
|
||||
const start = node.parent?.name === "FunctionDefinition" ? scope(node.parent.parent) : scope(node);
|
||||
const resolved = resolve(node, name, start);
|
||||
if (resolved) return resolved;
|
||||
@@ -423,8 +483,34 @@ export function pythonSyntaxRanges(
|
||||
tree.iterate({
|
||||
enter(cursor) {
|
||||
const node = cursor.node;
|
||||
if (!["VariableName", "PropertyName", "String", "Escape", "(", ")", "[", "]", "{", "}"].includes(node.name))
|
||||
if (
|
||||
![
|
||||
"VariableName",
|
||||
"PropertyName",
|
||||
"String",
|
||||
"FormatString",
|
||||
"type",
|
||||
"Escape",
|
||||
"(",
|
||||
")",
|
||||
"[",
|
||||
"]",
|
||||
"{",
|
||||
"}",
|
||||
].includes(node.name)
|
||||
)
|
||||
return;
|
||||
if (node.name === "FormatString") {
|
||||
const className = "cm-sem-python-fstring";
|
||||
let from = node.from;
|
||||
for (let child = node.firstChild; child; child = child.nextSibling) {
|
||||
if (child.name !== "FormatReplacement") continue;
|
||||
if (child.from > from) ranges.push({ from, to: child.from, className, source: "pythonSyntax" });
|
||||
from = child.to;
|
||||
}
|
||||
if (from < node.to) ranges.push({ from, to: node.to, className, source: "pythonSyntax" });
|
||||
return;
|
||||
}
|
||||
const text = doc.sliceString(node.from, node.to);
|
||||
const symbol = symbols.get(`${node.from}:${node.to}`);
|
||||
let style: string | undefined;
|
||||
@@ -433,7 +519,7 @@ export function pythonSyntaxRanges(
|
||||
else if (["[", "]"].includes(node.name)) style = "python-brackets";
|
||||
else if (["{", "}"].includes(node.name)) style = "python-braces";
|
||||
else if (node.name === "VariableName") {
|
||||
if (symbol === "typeParameter") className = pythonSymbolClasses(symbol);
|
||||
if (symbol === "typeParameter" || symbol === "unusedParameter") className = pythonSymbolClasses(symbol);
|
||||
else if (node.parent?.name === "FunctionDefinition") {
|
||||
if (symbol === "property") className = pythonSymbolClasses(symbol);
|
||||
else
|
||||
@@ -467,6 +553,7 @@ export function pythonSyntaxRanges(
|
||||
if (docstring && !/^[bf]/i.test(text)) style = "python-docstring";
|
||||
else if (/^[rub]*b[rub]*['"]/i.test(text)) style = "python-bytes";
|
||||
} else if (node.name === "Escape") style = "python-escape";
|
||||
else if (node.name === "type" && node.parent?.name === "TypeDefinition") style = "keyword";
|
||||
if (style) className = `cm-sem-${style}`;
|
||||
if (className) ranges.push({ from: node.from, to: node.to, className, source: "pythonSyntax" });
|
||||
if (style === "python-docstring") return false;
|
||||
|
||||
@@ -97,6 +97,7 @@ const PYTHON_VARIABLE_KINDS = new Set<PythonSymbolKind>([
|
||||
"constant",
|
||||
"property",
|
||||
"typeParameter",
|
||||
"unusedParameter",
|
||||
]);
|
||||
const PYTHON_SYMBOL_BASES = new Set([
|
||||
"cm-sem-variable",
|
||||
@@ -105,6 +106,7 @@ const PYTHON_SYMBOL_BASES = new Set([
|
||||
"cm-sem-constant",
|
||||
"cm-sem-type",
|
||||
"cm-sem-typeParameter",
|
||||
"cm-sem-parameter",
|
||||
"cm-sem-builtin",
|
||||
]);
|
||||
|
||||
|
||||
@@ -365,10 +365,14 @@ export const lspTheme = EditorView.theme({
|
||||
".cm-sem-python-braces": pythonStyle("python-braces", "punct"),
|
||||
".cm-sem-python-definition": pythonStyle("function", "function"),
|
||||
".cm-sem-python-nested": pythonStyle("python-nested-function", "function"),
|
||||
".cm-sem-python-predefined-definition": pythonStyle("python-predefined-definition", "function"),
|
||||
".cm-sem-python-predefined-usage": pythonStyle("python-predefined-usage", "self"),
|
||||
".cm-sem-python-predefined-definition": pythonStyle("python-predefined-definition", "predefined"),
|
||||
".cm-sem-python-predefined-usage": pythonStyle("python-predefined-usage", "predefined"),
|
||||
".cm-sem-python-docstring, .cm-sem-python-docstring *": pythonStyle("docstring", "string"),
|
||||
".cm-sem-python-bytes": pythonStyle("python-bytes", "string"),
|
||||
".cm-sem-python-fstring, .cm-sem-python-fstring .tok-string, .cm-sem-python-fstring .tok-string2": pythonStyle(
|
||||
"python-fstring",
|
||||
"string",
|
||||
),
|
||||
".cm-sem-python-escape": pythonStyle("escape", "escape"),
|
||||
".cm-sem-python-format": pythonStyle("python-format", "escape"),
|
||||
".cm-sem-python-keyword-arg": pythonStyle("keyword-arg", "param"),
|
||||
@@ -385,12 +389,13 @@ export const lspTheme = EditorView.theme({
|
||||
".cm-sem-variable": { color: "var(--syn-variable)" },
|
||||
".cm-sem-property": { color: "var(--syn-property)" },
|
||||
".cm-sem-parameter": { color: "var(--syn-param, var(--syn-variable))" },
|
||||
".cm-sem-parameter.cm-sem-unused": { color: "var(--fg-unused, var(--fg-faint))" },
|
||||
".cm-sem-self": { color: "var(--syn-self, var(--syn-keyword))" },
|
||||
".cm-sem-keyword": { color: "var(--syn-keyword)", fontWeight: "var(--syn-keyword-bold, inherit)" },
|
||||
// Before the builtin rule: library globals (`print`, `string`) keep the predefined colour.
|
||||
".cm-sem-global:not(.cm-sem-function)": { color: "var(--syn-global, inherit)" },
|
||||
".cm-sem-builtin:not(.cm-sem-function)": { color: "var(--syn-builtin, inherit)" },
|
||||
".cm-sem-builtin.cm-sem-python-builtin": pythonStyle("predefined", "builtin"),
|
||||
".cm-sem-builtin.cm-sem-python-builtin": pythonStyle("python-builtin", "builtin"),
|
||||
".cm-sem-static": { fontStyle: "var(--syn-static-italic, italic)" },
|
||||
".cm-sem-property.cm-sem-static, .cm-sem-property.cm-sem-static *": {
|
||||
color: "var(--syn-static-property, var(--syn-property))",
|
||||
|
||||
@@ -12,6 +12,13 @@ describe("color schemes", () => {
|
||||
expect(schemeTokens("light").get("--syn-keyword")).toBe("#0033b3");
|
||||
expect(schemeTokens("dark").get("--syn-keyword")).toBe("#cf8e6d");
|
||||
expect(schemeTokens("light").get("--bg-editor")).not.toMatch(/var\(/);
|
||||
const dark = schemeTokens("dark");
|
||||
expect(dark.get("--syn-python-builtin")).toBe("#8888c6");
|
||||
expect(dark.get("--syn-python-predefined-definition")).toBe("#b200b2");
|
||||
expect(dark.get("--syn-python-predefined-usage")).toBe("#b200b2");
|
||||
expect(dark.get("--syn-python-instance-attribute")).toBe("#bcbec4");
|
||||
expect(dark.get("--syn-python-fstring")).toBe("#a5c261");
|
||||
expect(dark.get("--syn-python-bytes")).toBe("#a5c261");
|
||||
});
|
||||
|
||||
it("gives PHP variables and function calls their own colours, as PhpStorm (#1532)", () => {
|
||||
|
||||
@@ -142,6 +142,7 @@ const BASE_ATTRIBUTES: readonly AttributeDef[] = [
|
||||
syn("pyBraces", "Braces", ["Python"], "python-braces"),
|
||||
syn("pyNestedFunction", "Nested function definition", ["Python"], "python-nested-function"),
|
||||
syn("pyBytes", "Byte string", ["Python"], "python-bytes"),
|
||||
syn("pyFString", "F-string", ["Python"], "python-fstring"),
|
||||
syn("pyPredefinedDefinition", "Predefined function definition", ["Python"], "python-predefined-definition"),
|
||||
syn("pyPredefinedUsage", "Predefined name usage", ["Python"], "python-predefined-usage"),
|
||||
syn("pyFormat", "Format specifier", ["Python"], "python-format"),
|
||||
@@ -156,7 +157,7 @@ const BASE_ATTRIBUTES: readonly AttributeDef[] = [
|
||||
},
|
||||
syn("pyKeywordArg", "Keyword argument", ["Python"], "keyword-arg"),
|
||||
syn("pyDocstring", "Docstring", ["Python"], "docstring"),
|
||||
syn("pyBuiltin", "Built-in name", ["Python"], "predefined"),
|
||||
syn("pyBuiltin", "Built-in name", ["Python"], "python-builtin"),
|
||||
syn("pyDecorator", "Decorator", ["Python"], "annotation"),
|
||||
syn("pyLocalVariable", "Local variable", ["Python"], "python-local-variable"),
|
||||
syn("pyGlobalVariable", "Global variable", ["Python"], "python-global-variable"),
|
||||
|
||||
@@ -122,6 +122,14 @@ describe(".icls schemes", () => {
|
||||
for (const [name, value] of names) expect(attrs[name]?.foreground).toBe(`#${value}`);
|
||||
});
|
||||
|
||||
it("imports the Python f-string colour", () => {
|
||||
const xml =
|
||||
'<scheme name="F"><attributes><option name="PY.STRING.F"><value>' +
|
||||
'<option name="FOREGROUND" value="808080"/></value></option></attributes></scheme>';
|
||||
const { id, customs } = importScheme({}, parseIcls(xml).scheme);
|
||||
expect(parseIcls(exportIcls(id, customs)).scheme.attributes.pyFString?.foreground).toBe("#808080");
|
||||
});
|
||||
|
||||
it("imports the global variable colour", () => {
|
||||
const xml =
|
||||
'<scheme name="G" parent_scheme="Darcula"><attributes><option name="DEFAULT_GLOBAL_VARIABLE"><value>' +
|
||||
|
||||
@@ -149,6 +149,7 @@ Object.assign(ATTRIBUTE_NAMES, {
|
||||
"PY.PREDEFINED_DEFINITION": "pyPredefinedDefinition",
|
||||
"PY.PREDEFINED_USAGE": "pyPredefinedUsage",
|
||||
"PY.STRING.B": "pyBytes",
|
||||
"PY.STRING.F": "pyFString",
|
||||
"PY.VALID_STRING_ESCAPE": "escape",
|
||||
"PY.OPERATION_SIGN": "operator",
|
||||
});
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
"Predefined name usage": "预定义名称引用",
|
||||
"Predefined function definition": "预定义函数定义",
|
||||
"Byte string": "字节字符串",
|
||||
"F-string": "F 字符串",
|
||||
"Nested function definition": "嵌套函数定义",
|
||||
"Local variable": "局部变量",
|
||||
"Global variable": "全局变量",
|
||||
|
||||
@@ -127,11 +127,16 @@ html {
|
||||
--syn-constant: #c77dbb;
|
||||
--syn-python-local-variable: var(--syn-variable);
|
||||
--syn-python-global-variable: var(--syn-global);
|
||||
--syn-python-instance-attribute: var(--syn-property);
|
||||
--syn-python-instance-attribute: var(--syn-variable);
|
||||
--syn-python-class-attribute: var(--syn-property);
|
||||
--syn-python-constant: var(--syn-constant);
|
||||
--syn-python-property: var(--syn-property);
|
||||
--syn-python-type-parameter: var(--syn-type);
|
||||
--syn-python-builtin: var(--syn-builtin);
|
||||
--syn-python-predefined-definition: var(--syn-predefined);
|
||||
--syn-python-predefined-usage: var(--syn-predefined);
|
||||
--syn-python-fstring: #a5c261;
|
||||
--syn-python-bytes: #a5c261;
|
||||
/* PhpStorm colours PHP variables and function calls on their own */
|
||||
--syn-php-variable: var(--syn-property);
|
||||
--syn-php-function-call: var(--syn-function);
|
||||
@@ -521,11 +526,16 @@ html {
|
||||
--syn-constant: #871094;
|
||||
--syn-python-local-variable: var(--syn-variable);
|
||||
--syn-python-global-variable: var(--syn-global);
|
||||
--syn-python-instance-attribute: var(--syn-property);
|
||||
--syn-python-instance-attribute: var(--syn-variable);
|
||||
--syn-python-class-attribute: var(--syn-property);
|
||||
--syn-python-constant: var(--syn-constant);
|
||||
--syn-python-property: var(--syn-property);
|
||||
--syn-python-type-parameter: var(--syn-type);
|
||||
--syn-python-builtin: var(--syn-builtin);
|
||||
--syn-python-predefined-definition: var(--syn-predefined);
|
||||
--syn-python-predefined-usage: var(--syn-predefined);
|
||||
--syn-python-fstring: var(--syn-string);
|
||||
--syn-python-bytes: var(--syn-string);
|
||||
--syn-php-variable: var(--syn-property);
|
||||
--syn-php-function-call: var(--syn-function);
|
||||
--syn-builtin: #000080;
|
||||
@@ -789,11 +799,16 @@ html {
|
||||
--syn-constant: #e0a0d6;
|
||||
--syn-python-local-variable: var(--syn-variable);
|
||||
--syn-python-global-variable: var(--syn-global);
|
||||
--syn-python-instance-attribute: var(--syn-property);
|
||||
--syn-python-instance-attribute: var(--syn-variable);
|
||||
--syn-python-class-attribute: var(--syn-property);
|
||||
--syn-python-constant: var(--syn-constant);
|
||||
--syn-python-property: var(--syn-property);
|
||||
--syn-python-type-parameter: var(--syn-type);
|
||||
--syn-python-builtin: var(--syn-builtin);
|
||||
--syn-python-predefined-definition: var(--syn-predefined);
|
||||
--syn-python-predefined-usage: var(--syn-predefined);
|
||||
--syn-python-fstring: var(--syn-string);
|
||||
--syn-python-bytes: var(--syn-string);
|
||||
--syn-php-variable: var(--syn-property);
|
||||
--syn-php-function-call: var(--syn-function);
|
||||
--syn-builtin: #b0b0f0;
|
||||
@@ -1142,11 +1157,16 @@ html {
|
||||
--syn-constant: var(--palette-number);
|
||||
--syn-python-local-variable: var(--syn-variable);
|
||||
--syn-python-global-variable: var(--syn-global);
|
||||
--syn-python-instance-attribute: var(--syn-property);
|
||||
--syn-python-instance-attribute: var(--syn-variable);
|
||||
--syn-python-class-attribute: var(--syn-property);
|
||||
--syn-python-constant: var(--syn-constant);
|
||||
--syn-python-property: var(--syn-property);
|
||||
--syn-python-type-parameter: var(--syn-type);
|
||||
--syn-python-builtin: var(--syn-builtin);
|
||||
--syn-python-predefined-definition: var(--syn-predefined);
|
||||
--syn-python-predefined-usage: var(--syn-predefined);
|
||||
--syn-python-fstring: var(--syn-string);
|
||||
--syn-python-bytes: var(--syn-string);
|
||||
--syn-php-variable: var(--syn-property);
|
||||
--syn-php-function-call: var(--syn-function);
|
||||
--syn-builtin: var(--palette-cyan);
|
||||
|
||||
Reference in new issue
Заблокувати користувача