From e83b6fc7d277b1c4b83b7297d702d6ac525aacfe Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Tue, 9 Mar 2021 17:47:10 +0100
Subject: [PATCH 01/63] Move to @codemirror/buildhelper
---
.gitignore | 3 ---
package.json | 6 ++----
rollup.config.js | 22 ----------------------
tsconfig.local.json | 19 -------------------
4 files changed, 2 insertions(+), 48 deletions(-)
delete mode 100644 rollup.config.js
delete mode 100644 tsconfig.local.json
diff --git a/.gitignore b/.gitignore
index 01bff1b..eebad72 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,6 @@
/node_modules
package-lock.json
/dist
-/src/*.js
-/src/*.d.ts
-/src/*.d.ts.map
/test/*.js
/test/*.d.ts
/test/*.d.ts.map
diff --git a/package.json b/package.json
index bc90561..0202daa 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "echo 'No tests'",
- "prepare": "tsc -p tsconfig.local.json && rollup -c"
+ "prepare": "cm-buildhelper src/python.ts"
},
"keywords": [
"editor",
@@ -31,9 +31,7 @@
"lezer-python": "^0.13.0"
},
"devDependencies": {
- "rollup": "^2.35.1",
- "rollup-plugin-dts": "^2.0.1",
- "typescript": "^4.1.3"
+ "@codemirror/buildhelper": "^0.1.0"
},
"repository": {
"type": "git",
diff --git a/rollup.config.js b/rollup.config.js
deleted file mode 100644
index 096deef..0000000
--- a/rollup.config.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import dts from "rollup-plugin-dts"
-
-export default [{
- input: "./src/python.js",
- external: id => id != "tslib" && !/^(\.?\/|\w:)/.test(id),
- output: [{
- format: "esm",
- file: "./dist/index.js",
- externalLiveBindings: false
- }, {
- format: "cjs",
- file: "./dist/index.cjs"
- }]
-}, {
- input: "./src/python.d.ts",
- output: {
- format: "esm",
- file: "./dist/index.d.ts",
- },
- plugins: [dts()],
- onwarn(warning, warn) { if (warning.code != "CIRCULAR_DEPENDENCY") warn(warning) }
-}]
diff --git a/tsconfig.local.json b/tsconfig.local.json
deleted file mode 100644
index 39f3353..0000000
--- a/tsconfig.local.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "compilerOptions": {
- "lib": ["es6", "dom", "scripthost"],
- "types": ["mocha"],
- "stripInternal": true,
- "noUnusedLocals": true,
- "strict": true,
- "target": "es6",
- "module": "es2020",
- "newLine": "lf",
- "declaration": true,
- "declarationMap": true,
- "moduleResolution": "node",
- "paths": {
- "@codemirror/lang-python": ["./src/python.ts"]
- }
- },
- "include": ["src/*.ts", "test/*.ts"]
-}
From c7c96a4c7df16eca7d41069f3e89137b79633c4d Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Mon, 26 Apr 2021 18:27:12 +0200
Subject: [PATCH 02/63] Use cm-runtests as the test script
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 0202daa..d6dcbac 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"version": "0.18.0",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
- "test": "echo 'No tests'",
+ "test": "cm-runtests",
"prepare": "cm-buildhelper src/python.ts"
},
"keywords": [
From 7192ceb844a0c60ea112807da3666fa415f08ddf Mon Sep 17 00:00:00 2001
From: Matt Hillsdon <44397098+microbit-matt-hillsdon@users.noreply.github.com>
Date: Mon, 24 May 2021 12:34:55 +0100
Subject: [PATCH 03/63] Fix typo in highlighting selector
FIX: Fix highlighting of property names.
---
src/python.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/python.ts b/src/python.ts
index 5bc1782..ff02fa6 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -28,7 +28,7 @@ export const pythonLanguage = LezerLanguage.define({
"FunctionDefinition/VariableName": t.function(t.definition(t.variableName)),
"ClassDefinition/VariableName": t.definition(t.className),
PropertyName: t.propertyName,
- "CallExpression/MemberExpression/ProperyName": t.function(t.propertyName),
+ "CallExpression/MemberExpression/PropertyName": t.function(t.propertyName),
Comment: t.lineComment,
Number: t.number,
String: t.string,
From 11078ad3fc08fac5eda676e363226eef2d65d0bb Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Tue, 20 Jul 2021 13:35:12 +0200
Subject: [PATCH 04/63] Improve indentation support
FIX: Don't deindent when pressing enter at the end of the document.
FIX: Properly indent else/elif/except syntax.
Issue https://github.com/codemirror/codemirror.next/issues/538
---
src/python.ts | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/python.ts b/src/python.ts
index ff02fa6..be689f4 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -9,7 +9,18 @@ export const pythonLanguage = LezerLanguage.define({
parser: parser.configure({
props: [
indentNodeProp.add({
- Body: continuedIndent()
+ Body: continuedIndent({except: /^\s*(else|elif|except|finally)\b/}),
+ Script: context => {
+ if (context.pos + /\s*/.exec(context.textAfter)![0].length < context.node.to)
+ return context.continue()
+ let endBody = null
+ for (let cur = context.node;;) {
+ let last = cur.lastChild
+ if (!last || last.type.name != "Body" || last.to != cur.to) break
+ endBody = cur = last
+ }
+ return endBody ? context.lineIndent(context.state.doc.lineAt(endBody.from)) + context.unit : null
+ }
}),
foldNodeProp.add({
"Body ArrayExpression DictionaryExpression": foldInside
@@ -51,7 +62,7 @@ export const pythonLanguage = LezerLanguage.define({
languageData: {
closeBrackets: {brackets: ["(", "[", "{", "'", '"', "'''", '"""']},
commentTokens: {line: "#"},
- indentOnInput: /^\s*[\}\]\)]$/
+ indentOnInput: /^\s*([\}\]\)]|else:|elif |except |finally:)$/
}
})
From dc79e548060277e049179ee6d8f98a37f283e566 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Tue, 20 Jul 2021 13:37:57 +0200
Subject: [PATCH 05/63] Mark version 0.18.1
---
CHANGELOG.md | 10 ++++++++++
package.json | 2 +-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1d8ebf0..698febe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+## 0.18.1 (2021-07-20)
+
+### Bug fixes
+
+Fix highlighting of property names. Improve indentation support
+
+Don't deindent when pressing enter at the end of the document.
+
+Properly indent else/elif/except syntax.
+
## 0.18.0 (2021-03-03)
### Breaking changes
diff --git a/package.json b/package.json
index d6dcbac..c205154 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "0.18.0",
+ "version": "0.18.1",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From 88b3998c2ec38c65f8115dc6a24eee0df47947c8 Mon Sep 17 00:00:00 2001
From: Matt Davies
Date: Tue, 20 Jul 2021 18:02:17 +0100
Subject: [PATCH 06/63] Add indentation in multiline dictionary, array or tuple
FIX: Improve indentation for dictionaries, arrays, and tuples.
---
src/python.ts | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/python.ts b/src/python.ts
index be689f4..c14998e 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -1,5 +1,5 @@
import {parser} from "lezer-python"
-import {continuedIndent, indentNodeProp, foldNodeProp, foldInside, LezerLanguage, LanguageSupport} from "@codemirror/language"
+import {continuedIndent, delimitedIndent, indentNodeProp, foldNodeProp, foldInside, LezerLanguage, LanguageSupport} from "@codemirror/language"
import {styleTags, tags as t} from "@codemirror/highlight"
/// A language provider based on the [Lezer Python
@@ -10,6 +10,9 @@ export const pythonLanguage = LezerLanguage.define({
props: [
indentNodeProp.add({
Body: continuedIndent({except: /^\s*(else|elif|except|finally)\b/}),
+ TupleExpression: delimitedIndent(),
+ DictionaryExpression: delimitedIndent(),
+ ArrayExpression: delimitedIndent(),
Script: context => {
if (context.pos + /\s*/.exec(context.textAfter)![0].length < context.node.to)
return context.continue()
From 18462e73470c78bd061a232896dc145cf5403acd Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Sat, 24 Jul 2021 14:22:36 +0200
Subject: [PATCH 07/63] Fix delimitedIndent calls
Issue https://github.com/codemirror/lang-python/pull/3
---
src/python.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/python.ts b/src/python.ts
index c14998e..09e214f 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -10,9 +10,9 @@ export const pythonLanguage = LezerLanguage.define({
props: [
indentNodeProp.add({
Body: continuedIndent({except: /^\s*(else|elif|except|finally)\b/}),
- TupleExpression: delimitedIndent(),
- DictionaryExpression: delimitedIndent(),
- ArrayExpression: delimitedIndent(),
+ TupleExpression: delimitedIndent({closing: ")"}),
+ DictionaryExpression: delimitedIndent({closing: "}"}),
+ ArrayExpression: delimitedIndent({closing: "]"}),
Script: context => {
if (context.pos + /\s*/.exec(context.textAfter)![0].length < context.node.to)
return context.continue()
From 32aad78e282cb1962bdbcc4b7da3e98f65e521f4 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Fri, 25 Jun 2021 19:07:37 +0200
Subject: [PATCH 08/63] Adjust to new Lezer package names
---
package.json | 2 +-
src/python.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index c205154..330ef35 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,7 @@
"dependencies": {
"@codemirror/highlight": "^0.18.0",
"@codemirror/language": "^0.18.0",
- "lezer-python": "^0.13.0"
+ "@lezer/python": "^0.14.0"
},
"devDependencies": {
"@codemirror/buildhelper": "^0.1.0"
diff --git a/src/python.ts b/src/python.ts
index 09e214f..564b770 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -1,4 +1,4 @@
-import {parser} from "lezer-python"
+import {parser} from "@lezer/python"
import {continuedIndent, delimitedIndent, indentNodeProp, foldNodeProp, foldInside, LezerLanguage, LanguageSupport} from "@codemirror/language"
import {styleTags, tags as t} from "@codemirror/highlight"
From 81b681cf4af860ecf8ce60997d8b0f38a6a09254 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Mon, 9 Aug 2021 10:30:15 +0200
Subject: [PATCH 09/63] Improve indentation at end of blocks
FIX: Indentation on deindented blank lines after a block will no longer
return to the block's indentation level.
Issue https://github.com/codemirror/lang-python/pull/4
---
src/python.ts | 45 ++++++++++++++++++++++++++++++------------
test/test-indent.ts | 48 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 80 insertions(+), 13 deletions(-)
create mode 100644 test/test-indent.ts
diff --git a/src/python.ts b/src/python.ts
index 564b770..07304bf 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -1,7 +1,22 @@
import {parser} from "@lezer/python"
-import {continuedIndent, delimitedIndent, indentNodeProp, foldNodeProp, foldInside, LezerLanguage, LanguageSupport} from "@codemirror/language"
+import {SyntaxNode} from "@lezer/common"
+import {delimitedIndent, indentNodeProp, TreeIndentContext,
+ foldNodeProp, foldInside, LezerLanguage, LanguageSupport} from "@codemirror/language"
import {styleTags, tags as t} from "@codemirror/highlight"
+function indentBody(context: TreeIndentContext, node: SyntaxNode) {
+ let base = context.lineIndent(node.from)
+ let line = context.lineAt(context.pos, -1), to = line.from + line.text.length
+ // Don't consider blank, deindented lines at the end of the
+ // block part of the block
+ if (!/\S/.test(line.text) &&
+ context.node.to < to + 100 &&
+ !/\S/.test(context.state.sliceDoc(to, context.node.to)) &&
+ context.lineIndent(context.pos, -1) <= base)
+ return null
+ return base + context.unit
+}
+
/// A language provider based on the [Lezer Python
/// parser](https://github.com/lezer-parser/python), extended with
/// highlighting and indentation information.
@@ -9,20 +24,24 @@ export const pythonLanguage = LezerLanguage.define({
parser: parser.configure({
props: [
indentNodeProp.add({
- Body: continuedIndent({except: /^\s*(else|elif|except|finally)\b/}),
- TupleExpression: delimitedIndent({closing: ")"}),
- DictionaryExpression: delimitedIndent({closing: "}"}),
- ArrayExpression: delimitedIndent({closing: "]"}),
+ Body: context => indentBody(context, context.node) ?? context.continue(),
+ "TupleExpression ComprehensionExpression ParamList ArgList ParenthesizedExpression": delimitedIndent({closing: ")"}),
+ "DictionaryExpression DictionaryComprehensionExpression SetExpression SetComprehensionExpression": delimitedIndent({closing: "}"}),
+ "ArrayExpression ArrayComprehensionExpression": delimitedIndent({closing: "]"}),
Script: context => {
- if (context.pos + /\s*/.exec(context.textAfter)![0].length < context.node.to)
- return context.continue()
- let endBody = null
- for (let cur = context.node;;) {
- let last = cur.lastChild
- if (!last || last.type.name != "Body" || last.to != cur.to) break
- endBody = cur = last
+ if (context.pos + /\s*/.exec(context.textAfter)![0].length >= context.node.to) {
+ let endBody = null
+ for (let cur: SyntaxNode | null = context.node, to = cur.to;;) {
+ cur = cur.lastChild
+ if (!cur || cur.to != to) break
+ if (cur.type.name == "Body") endBody = cur
+ }
+ if (endBody) {
+ let bodyIndent = indentBody(context, endBody)
+ if (bodyIndent != null) return bodyIndent
+ }
}
- return endBody ? context.lineIndent(context.state.doc.lineAt(endBody.from)) + context.unit : null
+ return context.continue()
}
}),
foldNodeProp.add({
diff --git a/test/test-indent.ts b/test/test-indent.ts
new file mode 100644
index 0000000..e117984
--- /dev/null
+++ b/test/test-indent.ts
@@ -0,0 +1,48 @@
+import ist from "ist"
+import {EditorState} from "@codemirror/state"
+import {getIndentation} from "@codemirror/language"
+import {python} from "@codemirror/lang-python"
+
+function check(code: string) {
+ return () => {
+ code = /^\n*([^]*)/.exec(code)![1]
+ let state = EditorState.create({doc: code, extensions: [python().language]})
+ for (let pos = 0, lines = code.split("\n"), i = 0; i < lines.length; i++) {
+ let line = lines[i], indent = /^\s*/.exec(line)![0].length
+ ist(`${getIndentation(state, pos)} (${i + 1})`, `${indent} (${i + 1})`)
+ pos += line.length + 1
+ }
+ }
+}
+
+describe("python indentation", () => {
+ it("indents bodies", check(`
+def foo():
+ bar
+ baz
+
+`))
+
+ it("indents function arg lists", check(`
+foo(
+ bar,
+ baz
+)`))
+
+ it("indents nested bodies", check(`
+def foo():
+ if True:
+ a
+ elif False:
+ b
+ else:
+ c
+`))
+
+ it("dedents except", check(`
+try:
+ foo()
+except e:
+ bar()
+`))
+})
From d8f189d4a5da8993be3cdb7ec840b9a588fa9395 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 11 Aug 2021 08:33:07 +0200
Subject: [PATCH 10/63] Follow LezerLanguage -> LRLanguage rename
---
src/python.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/python.ts b/src/python.ts
index 07304bf..f261384 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -1,7 +1,7 @@
import {parser} from "@lezer/python"
import {SyntaxNode} from "@lezer/common"
import {delimitedIndent, indentNodeProp, TreeIndentContext,
- foldNodeProp, foldInside, LezerLanguage, LanguageSupport} from "@codemirror/language"
+ foldNodeProp, foldInside, LRLanguage, LanguageSupport} from "@codemirror/language"
import {styleTags, tags as t} from "@codemirror/highlight"
function indentBody(context: TreeIndentContext, node: SyntaxNode) {
@@ -20,7 +20,7 @@ function indentBody(context: TreeIndentContext, node: SyntaxNode) {
/// A language provider based on the [Lezer Python
/// parser](https://github.com/lezer-parser/python), extended with
/// highlighting and indentation information.
-export const pythonLanguage = LezerLanguage.define({
+export const pythonLanguage = LRLanguage.define({
parser: parser.configure({
props: [
indentNodeProp.add({
From a0c78c4662696de936c91a3b3ae3c3f34971f436 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 11 Aug 2021 14:24:27 +0200
Subject: [PATCH 11/63] Mark version 0.19.0
---
CHANGELOG.md | 8 ++++++++
package.json | 6 +++---
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 698febe..0a1fd00 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 0.19.0 (2021-08-11)
+
+### Bug fixes
+
+Improve indentation for dictionaries, arrays, and tuples. Fix delimitedIndent calls
+
+Indentation on deindented blank lines after a block will no longer return to the block's indentation level.
+
## 0.18.1 (2021-07-20)
### Bug fixes
diff --git a/package.json b/package.json
index 330ef35..763875b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "0.18.1",
+ "version": "0.19.0",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
@@ -26,8 +26,8 @@
"sideEffects": false,
"license": "MIT",
"dependencies": {
- "@codemirror/highlight": "^0.18.0",
- "@codemirror/language": "^0.18.0",
+ "@codemirror/highlight": "^0.19.0",
+ "@codemirror/language": "^0.19.0",
"@lezer/python": "^0.14.0"
},
"devDependencies": {
From c78c4efb3df259ab557798bb82a2c8e0fbef9473 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 11 Aug 2021 15:25:26 +0200
Subject: [PATCH 12/63] Fix lezer dependency versions
FIX: Fix incorrect versions for @lezer dependencies.
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 763875b..27b7fd9 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,7 @@
"dependencies": {
"@codemirror/highlight": "^0.19.0",
"@codemirror/language": "^0.19.0",
- "@lezer/python": "^0.14.0"
+ "@lezer/python": "^0.15.0"
},
"devDependencies": {
"@codemirror/buildhelper": "^0.1.0"
From 5fde20b094528532fee12cdc9372aeb3d1ecaa0a Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 11 Aug 2021 15:27:08 +0200
Subject: [PATCH 13/63] Mark version 0.19.1
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0a1fd00..1387ca4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.19.1 (2021-08-11)
+
+### Bug fixes
+
+Fix incorrect versions for @lezer dependencies.
+
## 0.19.0 (2021-08-11)
### Bug fixes
diff --git a/package.json b/package.json
index 27b7fd9..451b4fb 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "0.19.0",
+ "version": "0.19.1",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From aec5ac8e482d9dcb1662e3ca52c174d02f5f5d49 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 11 Aug 2021 16:47:49 +0200
Subject: [PATCH 14/63] Further refine indentation behavior
FIX: Make sure that indenting an else/elif/except/finally that's indented too
deep moves it back up.
---
src/python.ts | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/python.ts b/src/python.ts
index f261384..2ce87ae 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -14,6 +14,11 @@ function indentBody(context: TreeIndentContext, node: SyntaxNode) {
!/\S/.test(context.state.sliceDoc(to, context.node.to)) &&
context.lineIndent(context.pos, -1) <= base)
return null
+ // A normally deindenting keyword that appears at a higher
+ // indentation than the block should probably be handled by the next
+ // level
+ if (/^\s*(else:|elif |except |finally:)/.test(context.textAfter) && context.lineIndent(context.pos, -1) > base)
+ return null
return base + context.unit
}
@@ -25,6 +30,8 @@ export const pythonLanguage = LRLanguage.define({
props: [
indentNodeProp.add({
Body: context => indentBody(context, context.node) ?? context.continue(),
+ IfStatement: cx => /^\s*(else:|elif )/.test(cx.textAfter) ? cx.baseIndent : cx.continue(),
+ TryStatement: cx => /^\s*(except |finally:)/.test(cx.textAfter) ? cx.baseIndent : cx.continue(),
"TupleExpression ComprehensionExpression ParamList ArgList ParenthesizedExpression": delimitedIndent({closing: ")"}),
"DictionaryExpression DictionaryComprehensionExpression SetExpression SetComprehensionExpression": delimitedIndent({closing: "}"}),
"ArrayExpression ArrayComprehensionExpression": delimitedIndent({closing: "]"}),
From 5c1aa7936ca579649026fd178934d2aa5e20c3e5 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 11 Aug 2021 16:47:53 +0200
Subject: [PATCH 15/63] Mark version 0.19.2
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1387ca4..a2298fa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.19.2 (2021-08-11)
+
+### Bug fixes
+
+Make sure that indenting an else/elif/except/finally that's indented too deep moves it back up.
+
## 0.19.1 (2021-08-11)
### Bug fixes
diff --git a/package.json b/package.json
index 451b4fb..07a087a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "0.19.1",
+ "version": "0.19.2",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From cdeca5b8251460c56bcdd460d10dad436854b117 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Mon, 3 Jan 2022 08:52:44 +0100
Subject: [PATCH 16/63] Use moduleKeyword tag
---
package.json | 2 +-
src/python.ts | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index 07a087a..546d8fc 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,7 @@
"sideEffects": false,
"license": "MIT",
"dependencies": {
- "@codemirror/highlight": "^0.19.0",
+ "@codemirror/highlight": "^0.19.7",
"@codemirror/language": "^0.19.0",
"@lezer/python": "^0.15.0"
},
diff --git a/src/python.ts b/src/python.ts
index 2ce87ae..c80e0c7 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -58,7 +58,8 @@ export const pythonLanguage = LRLanguage.define({
"async '*' '**' FormatConversion": t.modifier,
"for while if elif else try except finally return raise break continue with pass assert await yield": t.controlKeyword,
"in not and or is del": t.operatorKeyword,
- "import from def class global nonlocal lambda": t.definitionKeyword,
+ "from def class global nonlocal lambda": t.definitionKeyword,
+ import: t.moduleKeyword,
"with as print": t.keyword,
self: t.self,
Boolean: t.bool,
From f07ceef5be747af5b0e42aed67800bc41fde3378 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Thu, 20 Jan 2022 09:45:11 +0100
Subject: [PATCH 17/63] Fix fold logic for Body nodes
FIX: Fix the way block bodies are folded.
Closes https://github.com/codemirror/codemirror.next/issues/694
---
src/python.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/python.ts b/src/python.ts
index c80e0c7..e73282e 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -52,7 +52,8 @@ export const pythonLanguage = LRLanguage.define({
}
}),
foldNodeProp.add({
- "Body ArrayExpression DictionaryExpression": foldInside
+ "ArrayExpression DictionaryExpression": foldInside,
+ Body: node => ({from: node.from + 1, to: node.to})
}),
styleTags({
"async '*' '**' FormatConversion": t.modifier,
From 44f7cfd6cf123f03a521e605db17b118ab4083fe Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Thu, 20 Jan 2022 09:45:15 +0100
Subject: [PATCH 18/63] Mark version 0.19.3
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a2298fa..3dbe004 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.19.3 (2022-01-20)
+
+### Bug fixes
+
+Fix the way block bodies are folded.
+
## 0.19.2 (2021-08-11)
### Bug fixes
diff --git a/package.json b/package.json
index 546d8fc..307a018 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "0.19.2",
+ "version": "0.19.3",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From 33ce6b5f7e704ce6cb7813839ca5871ee2f93d20 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 26 Jan 2022 08:15:30 +0100
Subject: [PATCH 19/63] Don't fold across newline after bodies
FIX: Fix issue where folding body nodes folded away the newline after the body.
Closes https://github.com/codemirror/lang-python/pull/5
---
src/python.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/python.ts b/src/python.ts
index e73282e..5dab8ba 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -53,7 +53,7 @@ export const pythonLanguage = LRLanguage.define({
}),
foldNodeProp.add({
"ArrayExpression DictionaryExpression": foldInside,
- Body: node => ({from: node.from + 1, to: node.to})
+ Body: (node, state) => ({from: node.from + 1, to: node.to - (node.to == state.doc.length ? 0 : 1)})
}),
styleTags({
"async '*' '**' FormatConversion": t.modifier,
From 5da5c854bc75027a5fb7251c1869fff8fac155e3 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 26 Jan 2022 08:36:06 +0100
Subject: [PATCH 20/63] Mark version 0.19.4
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3dbe004..fa0d857 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.19.4 (2022-01-26)
+
+### Bug fixes
+
+Fix issue where folding body nodes folded away the newline after the body.
+
## 0.19.3 (2022-01-20)
### Bug fixes
diff --git a/package.json b/package.json
index 307a018..fef7f0c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "0.19.3",
+ "version": "0.19.4",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From 7eb62a5f4ec41f3ad112bac25bf71185a4fdf010 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Thu, 17 Mar 2022 09:42:32 +0100
Subject: [PATCH 21/63] Fix some mistakes in the highlighting information
FIX: Make sure * and ** modifiers are highlighted as such, add modifier tag for FormatSpec nodes.
Issue https://github.com/codemirror/codemirror.next/issues/771
---
src/python.ts | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/python.ts b/src/python.ts
index 5dab8ba..2d7c9c2 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -56,13 +56,12 @@ export const pythonLanguage = LRLanguage.define({
Body: (node, state) => ({from: node.from + 1, to: node.to - (node.to == state.doc.length ? 0 : 1)})
}),
styleTags({
- "async '*' '**' FormatConversion": t.modifier,
+ "async \"*\" \"**\" FormatConversion FormatSpec": t.modifier,
"for while if elif else try except finally return raise break continue with pass assert await yield": t.controlKeyword,
"in not and or is del": t.operatorKeyword,
"from def class global nonlocal lambda": t.definitionKeyword,
import: t.moduleKeyword,
"with as print": t.keyword,
- self: t.self,
Boolean: t.bool,
None: t.null,
VariableName: t.variableName,
From 805d6eac58489bc57aaa0d0d4975d6fccd167f0f Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 6 Apr 2022 08:44:39 +0200
Subject: [PATCH 22/63] Mark version 0.19.5
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa0d857..5ea0dbe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.19.5 (2022-04-06)
+
+### Bug fixes
+
+Make sure * and ** modifiers are highlighted as such, add modifier tag for FormatSpec nodes.
+
## 0.19.4 (2022-01-26)
### Bug fixes
diff --git a/package.json b/package.json
index fef7f0c..83e5f99 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "0.19.4",
+ "version": "0.19.5",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From 4fc7033ebfc712abbdcfcdf0817c326d85419cee Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Thu, 24 Mar 2022 09:56:00 +0100
Subject: [PATCH 23/63] Move highlighting information into @lezer/python
---
package.json | 1 -
src/python.ts | 33 ---------------------------------
2 files changed, 34 deletions(-)
diff --git a/package.json b/package.json
index 83e5f99..62aa245 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,6 @@
"sideEffects": false,
"license": "MIT",
"dependencies": {
- "@codemirror/highlight": "^0.19.7",
"@codemirror/language": "^0.19.0",
"@lezer/python": "^0.15.0"
},
diff --git a/src/python.ts b/src/python.ts
index 2d7c9c2..16efbc2 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -2,7 +2,6 @@ import {parser} from "@lezer/python"
import {SyntaxNode} from "@lezer/common"
import {delimitedIndent, indentNodeProp, TreeIndentContext,
foldNodeProp, foldInside, LRLanguage, LanguageSupport} from "@codemirror/language"
-import {styleTags, tags as t} from "@codemirror/highlight"
function indentBody(context: TreeIndentContext, node: SyntaxNode) {
let base = context.lineIndent(node.from)
@@ -54,38 +53,6 @@ export const pythonLanguage = LRLanguage.define({
foldNodeProp.add({
"ArrayExpression DictionaryExpression": foldInside,
Body: (node, state) => ({from: node.from + 1, to: node.to - (node.to == state.doc.length ? 0 : 1)})
- }),
- styleTags({
- "async \"*\" \"**\" FormatConversion FormatSpec": t.modifier,
- "for while if elif else try except finally return raise break continue with pass assert await yield": t.controlKeyword,
- "in not and or is del": t.operatorKeyword,
- "from def class global nonlocal lambda": t.definitionKeyword,
- import: t.moduleKeyword,
- "with as print": t.keyword,
- Boolean: t.bool,
- None: t.null,
- VariableName: t.variableName,
- "CallExpression/VariableName": t.function(t.variableName),
- "FunctionDefinition/VariableName": t.function(t.definition(t.variableName)),
- "ClassDefinition/VariableName": t.definition(t.className),
- PropertyName: t.propertyName,
- "CallExpression/MemberExpression/PropertyName": t.function(t.propertyName),
- Comment: t.lineComment,
- Number: t.number,
- String: t.string,
- FormatString: t.special(t.string),
- UpdateOp: t.updateOperator,
- ArithOp: t.arithmeticOperator,
- BitOp: t.bitwiseOperator,
- CompareOp: t.compareOperator,
- AssignOp: t.definitionOperator,
- Ellipsis: t.punctuation,
- At: t.meta,
- "( )": t.paren,
- "[ ]": t.squareBracket,
- "{ }": t.brace,
- ".": t.derefOperator,
- ", ;": t.separator
})
],
}),
From 8a085d967f6e6f4477287c96dc93323a6fb68b6d Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Tue, 19 Apr 2022 18:13:35 +0200
Subject: [PATCH 24/63] Allow set and tuple expressions to be folded
FIX: Add folding information for set and tuple expressions.
Closes https://github.com/codemirror/codemirror.next/issues/803
---
src/python.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/python.ts b/src/python.ts
index 16efbc2..5b43a02 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -51,7 +51,7 @@ export const pythonLanguage = LRLanguage.define({
}
}),
foldNodeProp.add({
- "ArrayExpression DictionaryExpression": foldInside,
+ "ArrayExpression DictionaryExpression SetExpression TupleExpression": foldInside,
Body: (node, state) => ({from: node.from + 1, to: node.to - (node.to == state.doc.length ? 0 : 1)})
})
],
From b92fa7945eda39067c64f362849a1e3ea8778e72 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 20 Apr 2022 15:54:51 +0200
Subject: [PATCH 25/63] Bump lezer version to 0.16.0
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 62aa245..c50bf9d 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,7 @@
"license": "MIT",
"dependencies": {
"@codemirror/language": "^0.19.0",
- "@lezer/python": "^0.15.0"
+ "@lezer/python": "^0.16.0"
},
"devDependencies": {
"@codemirror/buildhelper": "^0.1.0"
From 10c7a439f6f8141a3f91f2966759bea33be92244 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 20 Apr 2022 16:10:56 +0200
Subject: [PATCH 26/63] Mark version 0.20.0
---
CHANGELOG.md | 6 ++++++
package.json | 4 ++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5ea0dbe..d4f062b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.20.0 (2022-04-20)
+
+### Bug fixes
+
+Add folding information for set and tuple expressions.
+
## 0.19.5 (2022-04-06)
### Bug fixes
diff --git a/package.json b/package.json
index c50bf9d..db5e312 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "0.19.5",
+ "version": "0.20.0",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
@@ -26,7 +26,7 @@
"sideEffects": false,
"license": "MIT",
"dependencies": {
- "@codemirror/language": "^0.19.0",
+ "@codemirror/language": "^0.20.0",
"@lezer/python": "^0.16.0"
},
"devDependencies": {
From 3b30be2b6d12d34cdb4c5e540c88412d8a815d52 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 8 Jun 2022 08:45:27 +0200
Subject: [PATCH 27/63] Mark version 6.0.0
---
CHANGELOG.md | 6 ++++++
package.json | 6 +++---
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d4f062b..8a5197b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 6.0.0 (2022-06-08)
+
+### Breaking changes
+
+Update dependencies to 6.0.0
+
## 0.20.0 (2022-04-20)
### Bug fixes
diff --git a/package.json b/package.json
index db5e312..656be0f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "0.20.0",
+ "version": "6.0.0",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
@@ -26,8 +26,8 @@
"sideEffects": false,
"license": "MIT",
"dependencies": {
- "@codemirror/language": "^0.20.0",
- "@lezer/python": "^0.16.0"
+ "@codemirror/language": "^6.0.0",
+ "@lezer/python": "^1.0.0"
},
"devDependencies": {
"@codemirror/buildhelper": "^0.1.0"
From 9a16d237d36ace46b5c785f3f2cf93fdbb70756c Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 8 Jun 2022 10:02:41 +0200
Subject: [PATCH 28/63] Update website links in readme
---
README.md | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index 3059c4a..e322f9e 100644
--- a/README.md
+++ b/README.md
@@ -2,14 +2,14 @@
# @codemirror/lang-python [](https://www.npmjs.org/package/@codemirror/lang-python)
-[ [**WEBSITE**](https://codemirror.net/6/) | [**ISSUES**](https://github.com/codemirror/codemirror.next/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/lang-python/blob/main/CHANGELOG.md) ]
+[ [**WEBSITE**](https://codemirror.net/) | [**ISSUES**](https://github.com/codemirror/codemirror.next/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/lang-python/blob/main/CHANGELOG.md) ]
This package implements Python language support for the
-[CodeMirror](https://codemirror.net/6/) code editor.
+[CodeMirror](https://codemirror.net/) code editor.
-The [project page](https://codemirror.net/6/) has more information, a
-number of [examples](https://codemirror.net/6/examples/) and the
-[documentation](https://codemirror.net/6/docs/).
+The [project page](https://codemirror.net/) has more information, a
+number of [examples](https://codemirror.net/examples/) and the
+[documentation](https://codemirror.net/docs/).
This code is released under an
[MIT license](https://github.com/codemirror/lang-python/tree/main/LICENSE).
@@ -22,12 +22,12 @@ to communication around the project.
# API Reference
-
-
python() → LanguageSupport
+ python() → LanguageSupport
Python language support.
-
-
pythonLanguage: LezerLanguage
+ pythonLanguage: LezerLanguage
A language provider based on the Lezer Python
parser, extended with
From 8e5e499f5c1aa86c1932c0740d1599a52be035ff Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 8 Jun 2022 14:54:11 +0200
Subject: [PATCH 29/63] Follow repository rename
---
.github/workflows/dispatch.yml | 2 +-
README.md | 2 +-
src/README.md | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/dispatch.yml b/.github/workflows/dispatch.yml
index 9552050..d050072 100644
--- a/.github/workflows/dispatch.yml
+++ b/.github/workflows/dispatch.yml
@@ -11,6 +11,6 @@ jobs:
with:
# You should create a personal access token and store it in your repository
token: ${{ secrets.DISPATCH_AUTH }}
- repo: codemirror.next
+ repo: dev
owner: codemirror
event_type: push
diff --git a/README.md b/README.md
index e322f9e..388830b 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
# @codemirror/lang-python [](https://www.npmjs.org/package/@codemirror/lang-python)
-[ [**WEBSITE**](https://codemirror.net/) | [**ISSUES**](https://github.com/codemirror/codemirror.next/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/lang-python/blob/main/CHANGELOG.md) ]
+[ [**WEBSITE**](https://codemirror.net/) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/lang-python/blob/main/CHANGELOG.md) ]
This package implements Python language support for the
[CodeMirror](https://codemirror.net/) code editor.
diff --git a/src/README.md b/src/README.md
index 4fbafab..ea4b907 100644
--- a/src/README.md
+++ b/src/README.md
@@ -2,7 +2,7 @@
# @codemirror/lang-python [](https://www.npmjs.org/package/@codemirror/lang-python)
-[ [**WEBSITE**](https://codemirror.net/6/) | [**ISSUES**](https://github.com/codemirror/codemirror.next/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/lang-python/blob/main/CHANGELOG.md) ]
+[ [**WEBSITE**](https://codemirror.net/6/) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/lang-python/blob/main/CHANGELOG.md) ]
This package implements Python language support for the
[CodeMirror](https://codemirror.net/6/) code editor.
From d9f9b1a443369f85409f999cf048d59f938eccc9 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Thu, 21 Jul 2022 11:13:49 +0200
Subject: [PATCH 30/63] Properly return null for indentation in template
strings and comments
FIX: Fix (non-)auto indentation in template strings and comments.
Issue https://github.com/codemirror/dev/issues/909
---
src/python.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/python.ts b/src/python.ts
index 5b43a02..f80c47a 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -34,6 +34,7 @@ export const pythonLanguage = LRLanguage.define({
"TupleExpression ComprehensionExpression ParamList ArgList ParenthesizedExpression": delimitedIndent({closing: ")"}),
"DictionaryExpression DictionaryComprehensionExpression SetExpression SetComprehensionExpression": delimitedIndent({closing: "}"}),
"ArrayExpression ArrayComprehensionExpression": delimitedIndent({closing: "]"}),
+ "String FormatString": () => null,
Script: context => {
if (context.pos + /\s*/.exec(context.textAfter)![0].length >= context.node.to) {
let endBody = null
From 57cc9c8d0d4224e6b4b928e9110f6debd4123aca Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Thu, 21 Jul 2022 14:06:30 +0200
Subject: [PATCH 31/63] Mark version 6.0.1
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8a5197b..577cfc6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 6.0.1 (2022-07-21)
+
+### Bug fixes
+
+Fix (non-)auto indentation in template strings and comments.
+
## 6.0.0 (2022-06-08)
### Breaking changes
diff --git a/package.json b/package.json
index 656be0f..ff39bd6 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "6.0.0",
+ "version": "6.0.1",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From a2115adcf9b1d70ab0e335a1eeae2d9ea1a2dfbc Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Thu, 22 Sep 2022 13:04:30 +0200
Subject: [PATCH 32/63] Add string prefix metadata
FIX: Allow prefixed strings to be closed by `closeBrackets`.
---
src/python.ts | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/python.ts b/src/python.ts
index f80c47a..f68b5a5 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -58,7 +58,11 @@ export const pythonLanguage = LRLanguage.define({
],
}),
languageData: {
- closeBrackets: {brackets: ["(", "[", "{", "'", '"', "'''", '"""']},
+ closeBrackets: {
+ brackets: ["(", "[", "{", "'", '"', "'''", '"""'],
+ stringPrefixes: ["f", "fr", "rf", "r", "u", "b", "br", "rb",
+ "F", "FR", "RF", "R", "U", "B", "BR", "RB"]
+ },
commentTokens: {line: "#"},
indentOnInput: /^\s*([\}\]\)]|else:|elif |except |finally:)$/
}
From e92951d84f1b5dcaaa6b4bd5cecb72f72791cbbc Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Thu, 22 Sep 2022 17:04:22 +0200
Subject: [PATCH 33/63] Mark version 6.0.2
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 577cfc6..6e2649e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 6.0.2 (2022-09-22)
+
+### Bug fixes
+
+Allow prefixed strings to be closed by `closeBrackets`.
+
## 6.0.1 (2022-07-21)
### Bug fixes
diff --git a/package.json b/package.json
index ff39bd6..976b77b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "6.0.1",
+ "version": "6.0.2",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From 9da3502f4c4bcbf7d8556941f3c77c6c59a9479c Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 19 Oct 2022 18:08:58 +0200
Subject: [PATCH 34/63] Properly indent else clauses in try statements
FIX: Add proper indentation handling of `else` clauses in `try` statements.
Closes https://github.com/codemirror/dev/issues/976
---
src/python.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/python.ts b/src/python.ts
index f68b5a5..5a88892 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -30,7 +30,7 @@ export const pythonLanguage = LRLanguage.define({
indentNodeProp.add({
Body: context => indentBody(context, context.node) ?? context.continue(),
IfStatement: cx => /^\s*(else:|elif )/.test(cx.textAfter) ? cx.baseIndent : cx.continue(),
- TryStatement: cx => /^\s*(except |finally:)/.test(cx.textAfter) ? cx.baseIndent : cx.continue(),
+ TryStatement: cx => /^\s*(except |finally:|else:)/.test(cx.textAfter) ? cx.baseIndent : cx.continue(),
"TupleExpression ComprehensionExpression ParamList ArgList ParenthesizedExpression": delimitedIndent({closing: ")"}),
"DictionaryExpression DictionaryComprehensionExpression SetExpression SetComprehensionExpression": delimitedIndent({closing: "}"}),
"ArrayExpression ArrayComprehensionExpression": delimitedIndent({closing: "]"}),
From fa5898af9a71c747cb00dc22152c621eb7bf419a Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 19 Oct 2022 18:09:08 +0200
Subject: [PATCH 35/63] Mark version 6.0.3
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6e2649e..5ac81b0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 6.0.3 (2022-10-19)
+
+### Bug fixes
+
+Add proper indentation handling of `else` clauses in `try` statements.
+
## 6.0.2 (2022-09-22)
### Bug fixes
diff --git a/package.json b/package.json
index 976b77b..da59a2e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "6.0.2",
+ "version": "6.0.3",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From 4d019e554c8067252fd133bb1f2c4abeeca9a5c3 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Mon, 24 Oct 2022 13:56:15 +0200
Subject: [PATCH 36/63] Define a language name
FIX: Make sure the language object has a name.
---
src/python.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/python.ts b/src/python.ts
index 5a88892..8067085 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -25,6 +25,7 @@ function indentBody(context: TreeIndentContext, node: SyntaxNode) {
/// parser](https://github.com/lezer-parser/python), extended with
/// highlighting and indentation information.
export const pythonLanguage = LRLanguage.define({
+ name: "python",
parser: parser.configure({
props: [
indentNodeProp.add({
From bbb33acee911b2296e8a330f25939b5570c2ead1 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Mon, 24 Oct 2022 13:56:20 +0200
Subject: [PATCH 37/63] Mark version 6.0.4
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5ac81b0..b85d15d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 6.0.4 (2022-10-24)
+
+### Bug fixes
+
+Make sure the language object has a name.
+
## 6.0.3 (2022-10-19)
### Bug fixes
diff --git a/package.json b/package.json
index da59a2e..6612396 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "6.0.3",
+ "version": "6.0.4",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From 3926dd85711899e6cc2048db00f74322a0e40cab Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Fri, 18 Nov 2022 18:57:10 +0100
Subject: [PATCH 38/63] Add autocompletion support
FEATURE: The `globalCompletion` completion source (included in the language
support returned from `python()`) completes standard Python globals and
keywords.
FEATURE: Export a `localCompletionSource` function that completes locally
defined variables. Included in the support extensions returned from
`python()`.
---
package.json | 1 +
src/complete.ts | 189 ++++++++++++++++++++++++++++++++++++++++++++++++
src/python.ts | 7 +-
3 files changed, 196 insertions(+), 1 deletion(-)
create mode 100644 src/complete.ts
diff --git a/package.json b/package.json
index 6612396..862dc2d 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"sideEffects": false,
"license": "MIT",
"dependencies": {
+ "@codemirror/autocomplete": "^6.3.2",
"@codemirror/language": "^6.0.0",
"@lezer/python": "^1.0.0"
},
diff --git a/src/complete.ts b/src/complete.ts
new file mode 100644
index 0000000..ef9d76a
--- /dev/null
+++ b/src/complete.ts
@@ -0,0 +1,189 @@
+import {NodeWeakMap, SyntaxNodeRef, SyntaxNode, IterMode} from "@lezer/common"
+import {Completion, CompletionContext, CompletionResult, completeFromList, ifNotIn,
+ snippetCompletion as snip} from "@codemirror/autocomplete"
+import {syntaxTree} from "@codemirror/language"
+import {Text} from "@codemirror/state"
+
+const cache = new NodeWeakMap()
+
+const ScopeNodes = new Set([
+ "Script", "Body",
+ "FunctionDefinition", "ClassDefinition", "LambdaExpression",
+ "ForStatement", "MatchClause"
+])
+
+function defID(type: string) {
+ return (node: SyntaxNodeRef, def: (node: SyntaxNodeRef, type: string) => void, outer: boolean) => {
+ if (outer) return false
+ let id = node.node.getChild("VariableName")
+ if (id) def(id, type)
+ return true
+ }
+}
+
+const gatherCompletions: {
+ [node: string]: (node: SyntaxNodeRef, def: (node: SyntaxNodeRef, type: string) => void, outer: boolean) => void | boolean
+} = {
+ FunctionDefinition: defID("function"),
+ ClassDefinition: defID("class"),
+ ForStatement(node, def, outer) {
+ if (outer) for (let child = node.node.firstChild; child; child = child.nextSibling) {
+ if (child.name == "VariableName") def(child, "variable")
+ else if (child.name == "in") break
+ }
+ },
+ ImportStatement(_node, def) {
+ let {node} = _node
+ let isFrom = node.firstChild?.name == "from"
+ for (let ch = node.getChild("import"); ch; ch = ch.nextSibling) {
+ if (ch.name == "VariableName" && ch.nextSibling?.name != "as")
+ def(ch, isFrom ? "variable" : "namespace")
+ }
+ },
+ AssignStatement(node, def) {
+ for (let child = node.node.firstChild; child; child = child.nextSibling) {
+ if (child.name == "VariableName") def(child, "variable")
+ else if (child.name == ":" || child.name == "AssignOp") break
+ }
+ },
+ ParamList(node, def) {
+ for (let prev = null, child = node.node.firstChild; child; child = child.nextSibling) {
+ if (child.name == "VariableName" && (!prev || !/\*|AssignOp/.test(prev.name)))
+ def(child, "variable")
+ prev = child
+ }
+ },
+ CapturePattern: defID("variable"),
+ AsPattern: defID("variable"),
+ __proto__: null as any
+}
+
+function getScope(doc: Text, node: SyntaxNode) {
+ let cached = cache.get(node)
+ if (cached) return cached
+
+ console.log("get scope for", node.name)
+ let completions: Completion[] = [], top = true
+ function def(node: SyntaxNodeRef, type: string) {
+ let name = doc.sliceString(node.from, node.to)
+ completions.push({label: name, type})
+ }
+ node.cursor(IterMode.IncludeAnonymous).iterate(node => {
+ if (node.name) {
+ let gather = gatherCompletions[node.name]
+ if (gather && gather(node, def, top) || !top && ScopeNodes.has(node.name)) return console.log("bail for", node.name), false
+ top = false
+ } else if (node.to - node.from > 8192) {
+ // Allow caching for bigger internal nodes
+ for (let c of getScope(doc, node.node)) completions.push(c)
+ return false
+ }
+ })
+ cache.set(node, completions)
+ return completions
+}
+
+const Identifier = /^[\w\xa1-\uffff][\w\d\xa1-\uffff]*$/
+
+const dontComplete = ["String", "FormatString", "Comment", "PropertyName"]
+
+/// Completion source that looks up locally defined names in
+/// Python code.
+export function localCompletionSource(context: CompletionContext): CompletionResult | null {
+ let inner = syntaxTree(context.state).resolveInner(context.pos, -1)
+ if (dontComplete.indexOf(inner.name) > -1) return null
+ let isWord = inner.name == "VariableName" ||
+ inner.to - inner.from < 20 && Identifier.test(context.state.sliceDoc(inner.from, inner.to))
+ if (!isWord && !context.explicit) return null
+ let options: Completion[] = []
+ for (let pos: SyntaxNode | null = inner; pos; pos = pos.parent) {
+ if (ScopeNodes.has(pos.name)) options = options.concat(getScope(context.state.doc, pos))
+ }
+ return {
+ options,
+ from: isWord ? inner.from : context.pos,
+ validFor: Identifier
+ }
+}
+
+const globals: readonly Completion[] = [
+ "__annotations__", "__builtins__", "__debug__", "__doc__", "__import__", "__name__",
+ "__loader__", "__package__", "__spec__",
+ "False", "None", "True"
+].map(n => ({label: n, type: "constant"})).concat([
+ "ArithmeticError", "AssertionError", "AttributeError", "BaseException", "BlockingIOError",
+ "BrokenPipeError", "BufferError", "BytesWarning", "ChildProcessError", "ConnectionAbortedError",
+ "ConnectionError", "ConnectionRefusedError", "ConnectionResetError", "DeprecationWarning",
+ "EOFError", "Ellipsis", "EncodingWarning", "EnvironmentError", "Exception", "FileExistsError",
+ "FileNotFoundError", "FloatingPointError", "FutureWarning", "GeneratorExit", "IOError",
+ "ImportError", "ImportWarning", "IndentationError", "IndexError", "InterruptedError",
+ "IsADirectoryError", "KeyError", "KeyboardInterrupt", "LookupError", "MemoryError",
+ "ModuleNotFoundError", "NameError", "NotADirectoryError", "NotImplemented", "NotImplementedError",
+ "OSError", "OverflowError", "PendingDeprecationWarning", "PermissionError", "ProcessLookupError",
+ "RecursionError", "ReferenceError", "ResourceWarning", "RuntimeError", "RuntimeWarning",
+ "StopAsyncIteration", "StopIteration", "SyntaxError", "SyntaxWarning", "SystemError",
+ "SystemExit", "TabError", "TimeoutError", "TypeError", "UnboundLocalError", "UnicodeDecodeError",
+ "UnicodeEncodeError", "UnicodeError", "UnicodeTranslateError", "UnicodeWarning", "UserWarning",
+ "ValueError", "Warning", "ZeroDivisionError"
+].map(n => ({label: n, type: "type"}))).concat([
+ "bool", "bytearray", "bytes", "classmethod", "complex", "float", "frozenset", "int", "list",
+ "map", "memoryview", "object", "range", "set", "staticmethod", "str", "super", "tuple", "type"
+].map(n => ({label: n, type: "class"}))).concat([
+ "abs", "aiter", "all", "anext", "any", "ascii", "bin", "breakpoint", "callable", "chr",
+ "compile", "delattr", "dict", "dir", "divmod", "enumerate", "eval", "exec", "exit", "filter",
+ "format", "getattr", "globals", "hasattr", "hash", "help", "hex", "id", "input", "isinstance",
+ "issubclass", "iter", "len", "license", "locals", "max", "min", "next", "oct", "open",
+ "ord", "pow", "print", "property", "quit", "repr", "reversed", "round", "setattr", "slice",
+ "sorted", "sum", "vars", "zip"
+].map(n => ({label: n, type: "function"})))
+
+export const snippets: readonly Completion[] = [
+ snip("def ${name}(${params}):\n\t${}", {
+ label: "def",
+ detail: "function",
+ type: "keyword"
+ }),
+ snip("for ${name} in ${collection}:\n\t${}", {
+ label: "for",
+ detail: "loop",
+ type: "keyword"
+ }),
+ snip("while ${}:\n\t${}", {
+ label: "while",
+ detail: "loop",
+ type: "keyword"
+ }),
+ snip("try:\n\t${}\nexcept ${error}:\n\t${}", {
+ label: "try",
+ detail: "/ except block",
+ type: "keyword"
+ }),
+ snip("if ${}:\n\t\n", {
+ label: "if",
+ detail: "block",
+ type: "keyword"
+ }),
+ snip("if ${}:\n\t${}\nelse:\n\t${}", {
+ label: "if",
+ detail: "/ else block",
+ type: "keyword"
+ }),
+ snip("class ${name}:\n\tdef __init__(self, ${params}):\n\t\t\t${}", {
+ label: "class",
+ detail: "definition",
+ type: "keyword"
+ }),
+ snip("import ${module}", {
+ label: "import",
+ detail: "statement",
+ type: "keyword"
+ }),
+ snip("from ${module} import ${names}", {
+ label: "from",
+ detail: "import",
+ type: "keyword"
+ })
+]
+
+/// Autocompletion for built-in Python globals and keywords.
+export const globalCompletion = ifNotIn(dontComplete, completeFromList(globals.concat(snippets)))
diff --git a/src/python.ts b/src/python.ts
index 8067085..1deaafb 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -2,6 +2,8 @@ import {parser} from "@lezer/python"
import {SyntaxNode} from "@lezer/common"
import {delimitedIndent, indentNodeProp, TreeIndentContext,
foldNodeProp, foldInside, LRLanguage, LanguageSupport} from "@codemirror/language"
+import {globalCompletion, localCompletionSource} from "./complete"
+export {globalCompletion, localCompletionSource}
function indentBody(context: TreeIndentContext, node: SyntaxNode) {
let base = context.lineIndent(node.from)
@@ -71,5 +73,8 @@ export const pythonLanguage = LRLanguage.define({
/// Python language support.
export function python() {
- return new LanguageSupport(pythonLanguage)
+ return new LanguageSupport(pythonLanguage, [
+ pythonLanguage.data.of({autocomplete: localCompletionSource}),
+ pythonLanguage.data.of({autocomplete: globalCompletion}),
+ ])
}
From 53af280c20e61ed34cff33aece8c6a3eee7f316b Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Fri, 18 Nov 2022 18:57:53 +0100
Subject: [PATCH 39/63] Mark version 6.1.0
---
CHANGELOG.md | 8 ++++++++
package.json | 2 +-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b85d15d..5289513 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 6.1.0 (2022-11-18)
+
+### New features
+
+The `globalCompletion` completion source (included in the language support returned from `python()`) completes standard Python globals and keywords.
+
+Export a `localCompletionSource` function that completes locally defined variables. Included in the support extensions returned from `python()`.
+
## 6.0.4 (2022-10-24)
### Bug fixes
diff --git a/package.json b/package.json
index 862dc2d..39578e5 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "6.0.4",
+ "version": "6.1.0",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From eda7b8aa4f11e8bdf016cae618f4c7cdfabedbc6 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Sat, 24 Dec 2022 14:02:55 +0100
Subject: [PATCH 40/63] Remove debug statements
FIX: Remove leftover log statements.
Closes https://github.com/codemirror/dev/issues/1043
---
src/complete.ts | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/complete.ts b/src/complete.ts
index ef9d76a..8bcc566 100644
--- a/src/complete.ts
+++ b/src/complete.ts
@@ -62,7 +62,6 @@ function getScope(doc: Text, node: SyntaxNode) {
let cached = cache.get(node)
if (cached) return cached
- console.log("get scope for", node.name)
let completions: Completion[] = [], top = true
function def(node: SyntaxNodeRef, type: string) {
let name = doc.sliceString(node.from, node.to)
@@ -71,7 +70,7 @@ function getScope(doc: Text, node: SyntaxNode) {
node.cursor(IterMode.IncludeAnonymous).iterate(node => {
if (node.name) {
let gather = gatherCompletions[node.name]
- if (gather && gather(node, def, top) || !top && ScopeNodes.has(node.name)) return console.log("bail for", node.name), false
+ if (gather && gather(node, def, top) || !top && ScopeNodes.has(node.name)) return false
top = false
} else if (node.to - node.from > 8192) {
// Allow caching for bigger internal nodes
From d213e1ec9a483899c41712ed3dd805dbe436d15a Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Sat, 24 Dec 2022 14:02:58 +0100
Subject: [PATCH 41/63] Mark version 6.1.1
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5289513..eabdb6c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 6.1.1 (2022-12-24)
+
+### Bug fixes
+
+Remove leftover log statements.
+
## 6.1.0 (2022-11-18)
### New features
diff --git a/package.json b/package.json
index 39578e5..35c1b7f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "6.1.0",
+ "version": "6.1.1",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From 11ec1932249a9170c5a0dce11b3df23ab70dd66b Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Tue, 24 Jan 2023 08:20:09 +0100
Subject: [PATCH 42/63] Update maintainer email
---
LICENSE | 2 +-
package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/LICENSE b/LICENSE
index 3af12e6..9a91f48 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (C) 2018-2021 by Marijn Haverbeke and others
+Copyright (C) 2018-2021 by Marijn Haverbeke and others
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/package.json b/package.json
index 35c1b7f..66e1814 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,7 @@
],
"author": {
"name": "Marijn Haverbeke",
- "email": "marijnh@gmail.com",
+ "email": "marijn@haverbeke.berlin",
"url": "http://marijnhaverbeke.nl"
},
"type": "module",
From bcd3f34146b1246086b5155d698df1d04a7e7b8f Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Mon, 20 Feb 2023 09:42:39 +0100
Subject: [PATCH 43/63] Regenerate readme
---
README.md | 32 ++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)
diff --git a/README.md b/README.md
index 388830b..f734608 100644
--- a/README.md
+++ b/README.md
@@ -2,14 +2,14 @@
# @codemirror/lang-python [](https://www.npmjs.org/package/@codemirror/lang-python)
-[ [**WEBSITE**](https://codemirror.net/) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/lang-python/blob/main/CHANGELOG.md) ]
+[ [**WEBSITE**](https://codemirror.net/6/) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/lang-python/blob/main/CHANGELOG.md) ]
This package implements Python language support for the
-[CodeMirror](https://codemirror.net/) code editor.
+[CodeMirror](https://codemirror.net/6/) code editor.
-The [project page](https://codemirror.net/) has more information, a
-number of [examples](https://codemirror.net/examples/) and the
-[documentation](https://codemirror.net/docs/).
+The [project page](https://codemirror.net/6/) has more information, a
+number of [examples](https://codemirror.net/6/examples/) and the
+[documentation](https://codemirror.net/6/docs/).
This code is released under an
[MIT license](https://github.com/codemirror/lang-python/tree/main/LICENSE).
@@ -20,17 +20,29 @@ conduct](http://contributor-covenant.org/version/1/1/0/) that applies
to communication around the project.
# API Reference
+
--
-
python() → LanguageSupport
+-
+
globalCompletion: CompletionSource
-Python language support.
+Autocompletion for built-in Python globals and keywords.
+
+-
+
localCompletionSource(context: CompletionContext) → CompletionResult | null
+
+Completion source that looks up locally defined names in
+Python code.
-
-
pythonLanguage: LezerLanguage
+ pythonLanguage: LRLanguage
A language provider based on the Lezer Python
parser, extended with
highlighting and indentation information.
-
+-
+
python() → LanguageSupport
+
+Python language support.
+
+
\ No newline at end of file
From 5bd357c723462b6605bd3dec6b5f0203344b7d8e Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Mon, 20 Feb 2023 09:49:46 +0100
Subject: [PATCH 44/63] Update links in readme
---
README.md | 10 +++++-----
src/README.md | 10 +++++-----
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/README.md b/README.md
index f734608..91eed62 100644
--- a/README.md
+++ b/README.md
@@ -2,14 +2,14 @@
# @codemirror/lang-python [](https://www.npmjs.org/package/@codemirror/lang-python)
-[ [**WEBSITE**](https://codemirror.net/6/) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/lang-python/blob/main/CHANGELOG.md) ]
+[ [**WEBSITE**](https://codemirror.net/) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/lang-python/blob/main/CHANGELOG.md) ]
This package implements Python language support for the
-[CodeMirror](https://codemirror.net/6/) code editor.
+[CodeMirror](https://codemirror.net/) code editor.
-The [project page](https://codemirror.net/6/) has more information, a
-number of [examples](https://codemirror.net/6/examples/) and the
-[documentation](https://codemirror.net/6/docs/).
+The [project page](https://codemirror.net/) has more information, a
+number of [examples](https://codemirror.net/examples/) and the
+[documentation](https://codemirror.net/docs/).
This code is released under an
[MIT license](https://github.com/codemirror/lang-python/tree/main/LICENSE).
diff --git a/src/README.md b/src/README.md
index ea4b907..c3c7d2e 100644
--- a/src/README.md
+++ b/src/README.md
@@ -2,14 +2,14 @@
# @codemirror/lang-python [](https://www.npmjs.org/package/@codemirror/lang-python)
-[ [**WEBSITE**](https://codemirror.net/6/) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/lang-python/blob/main/CHANGELOG.md) ]
+[ [**WEBSITE**](https://codemirror.net/) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/lang-python/blob/main/CHANGELOG.md) ]
This package implements Python language support for the
-[CodeMirror](https://codemirror.net/6/) code editor.
+[CodeMirror](https://codemirror.net/) code editor.
-The [project page](https://codemirror.net/6/) has more information, a
-number of [examples](https://codemirror.net/6/examples/) and the
-[documentation](https://codemirror.net/6/docs/).
+The [project page](https://codemirror.net/) has more information, a
+number of [examples](https://codemirror.net/examples/) and the
+[documentation](https://codemirror.net/docs/).
This code is released under an
[MIT license](https://github.com/codemirror/lang-python/tree/main/LICENSE).
From e4e2540c4acbc40d055c08c4bdf0f79b78dcf1ed Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Tue, 28 Feb 2023 10:25:05 +0100
Subject: [PATCH 45/63] Don't indent for blocks that end in a deindented
comment line
FIX: Don't indent lines after a dedented comment line.
Closes https://github.com/codemirror/dev/issues/1094
---
src/python.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/python.ts b/src/python.ts
index 1deaafb..1cacfa8 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -10,7 +10,7 @@ function indentBody(context: TreeIndentContext, node: SyntaxNode) {
let line = context.lineAt(context.pos, -1), to = line.from + line.text.length
// Don't consider blank, deindented lines at the end of the
// block part of the block
- if (!/\S/.test(line.text) &&
+ if (/^\s*($|#)/.test(line.text) &&
context.node.to < to + 100 &&
!/\S/.test(context.state.sliceDoc(to, context.node.to)) &&
context.lineIndent(context.pos, -1) <= base)
From 8b033f0aed777b9eda0307cf5d1e492040fc9c1c Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 1 Mar 2023 09:14:17 +0100
Subject: [PATCH 46/63] Mark version 6.1.2
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index eabdb6c..2d897e5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 6.1.2 (2023-03-01)
+
+### Bug fixes
+
+Don't indent lines after a dedented comment line.
+
## 6.1.1 (2022-12-24)
### Bug fixes
diff --git a/package.json b/package.json
index 66e1814..1552f89 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "6.1.1",
+ "version": "6.1.2",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From 1f8d660b515672748f066038a972dfc4b72726b9 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Thu, 30 Mar 2023 13:44:16 +0200
Subject: [PATCH 47/63] Remove a kludge made unnecessary by an upstream change
---
package.json | 2 +-
src/python.ts | 8 --------
2 files changed, 1 insertion(+), 9 deletions(-)
diff --git a/package.json b/package.json
index 1552f89..8ac1a20 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,7 @@
"dependencies": {
"@codemirror/autocomplete": "^6.3.2",
"@codemirror/language": "^6.0.0",
- "@lezer/python": "^1.0.0"
+ "@lezer/python": "^1.1.4"
},
"devDependencies": {
"@codemirror/buildhelper": "^0.1.0"
diff --git a/src/python.ts b/src/python.ts
index 1cacfa8..2d500b5 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -7,14 +7,6 @@ export {globalCompletion, localCompletionSource}
function indentBody(context: TreeIndentContext, node: SyntaxNode) {
let base = context.lineIndent(node.from)
- let line = context.lineAt(context.pos, -1), to = line.from + line.text.length
- // Don't consider blank, deindented lines at the end of the
- // block part of the block
- if (/^\s*($|#)/.test(line.text) &&
- context.node.to < to + 100 &&
- !/\S/.test(context.state.sliceDoc(to, context.node.to)) &&
- context.lineIndent(context.pos, -1) <= base)
- return null
// A normally deindenting keyword that appears at a higher
// indentation than the block should probably be handled by the next
// level
From 1fe52ea9e286980aee63918b8b417a6f69325d7b Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Thu, 30 Mar 2023 14:31:48 +0200
Subject: [PATCH 48/63] Restore removed code
Seems it did more than I thought
---
src/python.ts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/python.ts b/src/python.ts
index 2d500b5..1cacfa8 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -7,6 +7,14 @@ export {globalCompletion, localCompletionSource}
function indentBody(context: TreeIndentContext, node: SyntaxNode) {
let base = context.lineIndent(node.from)
+ let line = context.lineAt(context.pos, -1), to = line.from + line.text.length
+ // Don't consider blank, deindented lines at the end of the
+ // block part of the block
+ if (/^\s*($|#)/.test(line.text) &&
+ context.node.to < to + 100 &&
+ !/\S/.test(context.state.sliceDoc(to, context.node.to)) &&
+ context.lineIndent(context.pos, -1) <= base)
+ return null
// A normally deindenting keyword that appears at a higher
// indentation than the block should probably be handled by the next
// level
From 73a4909277e25e706365f04be4de31b7ef7f6e20 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Thu, 25 May 2023 12:15:05 +0200
Subject: [PATCH 49/63] Move to @codemirror/buildhelper 1.0.0
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 8ac1a20..6eca967 100644
--- a/package.json
+++ b/package.json
@@ -31,7 +31,7 @@
"@lezer/python": "^1.1.4"
},
"devDependencies": {
- "@codemirror/buildhelper": "^0.1.0"
+ "@codemirror/buildhelper": "^1.0.0"
},
"repository": {
"type": "git",
From b9203eec74b8f4cd877b7fbf2a024b7a4b761727 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Mon, 12 Jun 2023 08:04:35 +0200
Subject: [PATCH 50/63] Properly determine a base indentation when indenting a
block
FIX: Fix a bug where blocks started after a wrapped argument list or similar
construct were indented too far.
Closes https://github.com/codemirror/dev/issues/1182
---
package.json | 2 +-
src/python.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index 6eca967..bf62251 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,7 @@
"license": "MIT",
"dependencies": {
"@codemirror/autocomplete": "^6.3.2",
- "@codemirror/language": "^6.0.0",
+ "@codemirror/language": "^6.8.0",
"@lezer/python": "^1.1.4"
},
"devDependencies": {
diff --git a/src/python.ts b/src/python.ts
index 1cacfa8..9c545e1 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -6,7 +6,7 @@ import {globalCompletion, localCompletionSource} from "./complete"
export {globalCompletion, localCompletionSource}
function indentBody(context: TreeIndentContext, node: SyntaxNode) {
- let base = context.lineIndent(node.from)
+ let base = context.baseIndentFor(node)
let line = context.lineAt(context.pos, -1), to = line.from + line.text.length
// Don't consider blank, deindented lines at the end of the
// block part of the block
From d87154ec7014063e6c7e0dfe16c2a7be93471114 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Mon, 12 Jun 2023 08:04:43 +0200
Subject: [PATCH 51/63] Mark version 6.1.3
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2d897e5..1987b4e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 6.1.3 (2023-06-12)
+
+### Bug fixes
+
+Fix a bug where blocks started after a wrapped argument list or similar construct were indented too far.
+
## 6.1.2 (2023-03-01)
### Bug fixes
diff --git a/package.json b/package.json
index bf62251..9b4d904 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "6.1.2",
+ "version": "6.1.3",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From 6676fd517325a04d8d03fbbc2e903242d1d45996 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Fri, 2 Feb 2024 22:25:14 +0100
Subject: [PATCH 52/63] Declare missing dependencies
FIX: Explicitly declare dependencies on @lezer/common and @codemirror/state
Closes https://github.com/codemirror/lang-liquid/issues/3
---
package.json | 2 ++
1 file changed, 2 insertions(+)
diff --git a/package.json b/package.json
index 9b4d904..2c71a39 100644
--- a/package.json
+++ b/package.json
@@ -26,8 +26,10 @@
"sideEffects": false,
"license": "MIT",
"dependencies": {
+ "@codemirror/state": "^6.0.0",
"@codemirror/autocomplete": "^6.3.2",
"@codemirror/language": "^6.8.0",
+ "@lezer/common": "^1.2.1",
"@lezer/python": "^1.1.4"
},
"devDependencies": {
From ce4804b2163180989a95d368ffdfa68d48f8d991 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Fri, 2 Feb 2024 22:25:25 +0100
Subject: [PATCH 53/63] Mark version 6.1.4
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1987b4e..9db5c95 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 6.1.4 (2024-02-02)
+
+### Bug fixes
+
+Explicitly declare dependencies on @lezer/common and @codemirror/state
+
## 6.1.3 (2023-06-12)
### Bug fixes
diff --git a/package.json b/package.json
index 2c71a39..efa4ad8 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "6.1.3",
+ "version": "6.1.4",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From 0cf35932e6706d371bde5d5e8464172b2ad61164 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Thu, 28 Mar 2024 22:13:58 +0100
Subject: [PATCH 54/63] Improve indentation of else line under for/while loops
FIX: Properly indent `else:` when attached to a `for` or `while`
statement.
Closes https://github.com/codemirror/dev/issues/1363
---
src/python.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/python.ts b/src/python.ts
index 9c545e1..000fda2 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -33,6 +33,7 @@ export const pythonLanguage = LRLanguage.define({
indentNodeProp.add({
Body: context => indentBody(context, context.node) ?? context.continue(),
IfStatement: cx => /^\s*(else:|elif )/.test(cx.textAfter) ? cx.baseIndent : cx.continue(),
+ "ForStatement WhileStatement": cx => /^\s*else:/.test(cx.textAfter) ? cx.baseIndent : cx.continue(),
TryStatement: cx => /^\s*(except |finally:|else:)/.test(cx.textAfter) ? cx.baseIndent : cx.continue(),
"TupleExpression ComprehensionExpression ParamList ArgList ParenthesizedExpression": delimitedIndent({closing: ")"}),
"DictionaryExpression DictionaryComprehensionExpression SetExpression SetComprehensionExpression": delimitedIndent({closing: "}"}),
From cc69f687f582366af5245472a775351d0fcb8f48 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Thu, 28 Mar 2024 22:14:10 +0100
Subject: [PATCH 55/63] Mark version 6.1.5
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9db5c95..234cab8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 6.1.5 (2024-03-28)
+
+### Bug fixes
+
+Properly indent `else:` when attached to a `for` or `while` statement.
+
## 6.1.4 (2024-02-02)
### Bug fixes
diff --git a/package.json b/package.json
index efa4ad8..ed0eafe 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "6.1.4",
+ "version": "6.1.5",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From 0468622ddfee9c2a0011544c8f3128749b714168 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Mon, 29 Apr 2024 13:41:13 +0200
Subject: [PATCH 56/63] Base continued body in indentation on the indentation
of the line before
FIX: Improve the way indentation for the current body is preserved
when inenting new lines.
Issue https://github.com/codemirror/dev/issues/1370
---
src/python.ts | 42 ++++++++++++++++++++++++++++--------------
1 file changed, 28 insertions(+), 14 deletions(-)
diff --git a/src/python.ts b/src/python.ts
index 000fda2..97f5bd6 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -5,6 +5,28 @@ import {delimitedIndent, indentNodeProp, TreeIndentContext,
import {globalCompletion, localCompletionSource} from "./complete"
export {globalCompletion, localCompletionSource}
+function innerBody(context: TreeIndentContext) {
+ let {node, pos} = context
+ let lineIndent = context.lineIndent(pos, -1)
+ let found = null
+ for (;;) {
+ let before = node.childBefore(pos)
+ if (!before) {
+ break
+ } else if (before.name == "Comment") {
+ pos = before.from
+ } else if (before.name == "Body") {
+ if (context.baseIndentFor(before) + context.unit <= lineIndent) found = before
+ node = before
+ } else if (before.type.is("Statement")) {
+ node = before
+ } else {
+ break
+ }
+ }
+ return found
+}
+
function indentBody(context: TreeIndentContext, node: SyntaxNode) {
let base = context.baseIndentFor(node)
let line = context.lineAt(context.pos, -1), to = line.from + line.text.length
@@ -31,7 +53,10 @@ export const pythonLanguage = LRLanguage.define({
parser: parser.configure({
props: [
indentNodeProp.add({
- Body: context => indentBody(context, context.node) ?? context.continue(),
+ Body: context => {
+ let inner = innerBody(context)
+ return indentBody(context, inner || context.node) ?? context.continue()
+ },
IfStatement: cx => /^\s*(else:|elif )/.test(cx.textAfter) ? cx.baseIndent : cx.continue(),
"ForStatement WhileStatement": cx => /^\s*else:/.test(cx.textAfter) ? cx.baseIndent : cx.continue(),
TryStatement: cx => /^\s*(except |finally:|else:)/.test(cx.textAfter) ? cx.baseIndent : cx.continue(),
@@ -40,19 +65,8 @@ export const pythonLanguage = LRLanguage.define({
"ArrayExpression ArrayComprehensionExpression": delimitedIndent({closing: "]"}),
"String FormatString": () => null,
Script: context => {
- if (context.pos + /\s*/.exec(context.textAfter)![0].length >= context.node.to) {
- let endBody = null
- for (let cur: SyntaxNode | null = context.node, to = cur.to;;) {
- cur = cur.lastChild
- if (!cur || cur.to != to) break
- if (cur.type.name == "Body") endBody = cur
- }
- if (endBody) {
- let bodyIndent = indentBody(context, endBody)
- if (bodyIndent != null) return bodyIndent
- }
- }
- return context.continue()
+ let inner = innerBody(context)
+ return (inner && indentBody(context, inner)) ?? context.continue()
}
}),
foldNodeProp.add({
From 83ed6b3ee13b6d65755ade185a018d469721210c Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Mon, 29 Apr 2024 17:52:39 +0200
Subject: [PATCH 57/63] Mark version 6.1.6
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 234cab8..2e0327e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 6.1.6 (2024-04-29)
+
+### Bug fixes
+
+Improve the way indentation for the current body is preserved when inenting new lines.
+
## 6.1.5 (2024-03-28)
### Bug fixes
diff --git a/package.json b/package.json
index ed0eafe..5bf17ed 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "6.1.5",
+ "version": "6.1.6",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From fec0c165b508ae5f862019cdcf2c2ec3c8bf83e8 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Mon, 30 Dec 2024 20:07:12 +0100
Subject: [PATCH 58/63] Add a usage section to readme
---
README.md | 39 ++++++++++++++++++++++++++-------------
src/README.md | 19 ++++++++++++++++++-
2 files changed, 44 insertions(+), 14 deletions(-)
diff --git a/README.md b/README.md
index 91eed62..7356dae 100644
--- a/README.md
+++ b/README.md
@@ -19,19 +19,26 @@ we have a [code of
conduct](http://contributor-covenant.org/version/1/1/0/) that applies
to communication around the project.
+## Usage
+
+```javascript
+import {EditorView, basicSetup} from "codemirror"
+import {python} from "@codemirror/lang-python"
+
+const view = new EditorView({
+ parent: document.body,
+ doc: `print("Hello world")`,
+ extensions: [basicSetup, python()]
+})
+```
+
# API Reference
--
-
globalCompletion: CompletionSource
-
-Autocompletion for built-in Python globals and keywords.
-
--
-
localCompletionSource(context: CompletionContext) → CompletionResult | null
+-
+
python() → LanguageSupport
-Completion source that looks up locally defined names in
-Python code.
+Python language support.
-
pythonLanguage: LRLanguage
@@ -40,9 +47,15 @@ Python code.
parser, extended with
highlighting and indentation information.
-
- python() → LanguageSupport
+
+ globalCompletion: CompletionSource
-Python language support.
+Autocompletion for built-in Python globals and keywords.
+
+
+ localCompletionSource(context: CompletionContext) → CompletionResult | null
+
+Completion source that looks up locally defined names in
+Python code.
-
\ No newline at end of file
+
diff --git a/src/README.md b/src/README.md
index c3c7d2e..1ae9876 100644
--- a/src/README.md
+++ b/src/README.md
@@ -19,8 +19,25 @@ we have a [code of
conduct](http://contributor-covenant.org/version/1/1/0/) that applies
to communication around the project.
+## Usage
+
+```javascript
+import {EditorView, basicSetup} from "codemirror"
+import {python} from "@codemirror/lang-python"
+
+const view = new EditorView({
+ parent: document.body,
+ doc: `print("Hello world")`,
+ extensions: [basicSetup, python()]
+})
+```
+
# API Reference
@python
-@pythonLanguage
\ No newline at end of file
+@pythonLanguage
+
+@globalCompletion
+
+@localCompletionSource
From 0f6499aac3eea5f01d463b484f5da742189c8f4b Mon Sep 17 00:00:00 2001
From: TechnoHouse <13776377+deephbz@users.noreply.github.com>
Date: Sat, 18 Jan 2025 19:35:02 +0800
Subject: [PATCH 59/63] Indentation for match-case statements
FIX: Properly indent match/case statements.
---
src/python.ts | 21 +++++-
test/test-indent.ts | 161 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 178 insertions(+), 4 deletions(-)
diff --git a/src/python.ts b/src/python.ts
index 97f5bd6..d4d2d65 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -15,9 +15,11 @@ function innerBody(context: TreeIndentContext) {
break
} else if (before.name == "Comment") {
pos = before.from
- } else if (before.name == "Body") {
+ } else if (before.name == "Body" || before.name == "MatchBody") {
if (context.baseIndentFor(before) + context.unit <= lineIndent) found = before
node = before
+ } else if (before.name == "MatchClause") {
+ node = before
} else if (before.type.is("Statement")) {
node = before
} else {
@@ -40,7 +42,7 @@ function indentBody(context: TreeIndentContext, node: SyntaxNode) {
// A normally deindenting keyword that appears at a higher
// indentation than the block should probably be handled by the next
// level
- if (/^\s*(else:|elif |except |finally:)/.test(context.textAfter) && context.lineIndent(context.pos, -1) > base)
+ if (/^\s*(else:|elif |except |finally:|case\s+[^=:]+:)/.test(context.textAfter) && context.lineIndent(context.pos, -1) > base)
return null
return base + context.unit
}
@@ -57,9 +59,20 @@ export const pythonLanguage = LRLanguage.define({
let inner = innerBody(context)
return indentBody(context, inner || context.node) ?? context.continue()
},
+
+ MatchBody: context => {
+ let inner = innerBody(context)
+ return indentBody(context, inner || context.node) ?? context.continue()
+ },
+
IfStatement: cx => /^\s*(else:|elif )/.test(cx.textAfter) ? cx.baseIndent : cx.continue(),
"ForStatement WhileStatement": cx => /^\s*else:/.test(cx.textAfter) ? cx.baseIndent : cx.continue(),
TryStatement: cx => /^\s*(except |finally:|else:)/.test(cx.textAfter) ? cx.baseIndent : cx.continue(),
+ MatchStatement: cx => {
+ if (/^\s*case /.test(cx.textAfter)) return cx.baseIndent + cx.unit
+ return cx.continue()
+ },
+
"TupleExpression ComprehensionExpression ParamList ArgList ParenthesizedExpression": delimitedIndent({closing: ")"}),
"DictionaryExpression DictionaryComprehensionExpression SetExpression SetComprehensionExpression": delimitedIndent({closing: "}"}),
"ArrayExpression ArrayComprehensionExpression": delimitedIndent({closing: "]"}),
@@ -69,6 +82,7 @@ export const pythonLanguage = LRLanguage.define({
return (inner && indentBody(context, inner)) ?? context.continue()
}
}),
+
foldNodeProp.add({
"ArrayExpression DictionaryExpression SetExpression TupleExpression": foldInside,
Body: (node, state) => ({from: node.from + 1, to: node.to - (node.to == state.doc.length ? 0 : 1)})
@@ -82,7 +96,8 @@ export const pythonLanguage = LRLanguage.define({
"F", "FR", "RF", "R", "U", "B", "BR", "RB"]
},
commentTokens: {line: "#"},
- indentOnInput: /^\s*([\}\]\)]|else:|elif |except |finally:)$/
+ // Indent logic logic are triggered upon below input patterns
+ indentOnInput: /^\s*([\}\]\)]|else:|elif |except |finally:|case\s+[^:]*:?)$/,
}
})
diff --git a/test/test-indent.ts b/test/test-indent.ts
index e117984..513e1d4 100644
--- a/test/test-indent.ts
+++ b/test/test-indent.ts
@@ -9,7 +9,7 @@ function check(code: string) {
let state = EditorState.create({doc: code, extensions: [python().language]})
for (let pos = 0, lines = code.split("\n"), i = 0; i < lines.length; i++) {
let line = lines[i], indent = /^\s*/.exec(line)![0].length
- ist(`${getIndentation(state, pos)} (${i + 1})`, `${indent} (${i + 1})`)
+ ist(`indent=${getIndentation(state, pos)} (line-numer=${i + 1})`, `indent=${indent} (line-numer=${i + 1})`)
pos += line.length + 1
}
}
@@ -45,4 +45,163 @@ try:
except e:
bar()
`))
+
+ it("multi-line-block try-except", check(`
+try:
+ foo()
+ fooz()
+except e:
+ bar()
+ barz()
+finally:
+ baz()
+ bazz()
+`))
+
+
+ it("multi-line-nested-block try-except", check(`
+try:
+ foo()
+ fooz()
+ try:
+ inner()
+ inner2()
+ except e2:
+ f3()
+ f4()
+ else:
+ f5()
+ f6()
+ finally:
+ f7()
+ f8()
+except e:
+ bar()
+ barz()
+finally:
+ baz()
+ bazz()
+`))
+
+ it("match-case", check(`
+match x:
+ case 1:
+ foo()
+ case 2:
+ bar()
+ case _:
+ bar()
+`))
+
+ it("match-case-multi-line-block", check(`
+def func():
+ match x:
+ case 1:
+ foo()
+ fooz()
+ case 2:
+ bar()
+ bar()
+ bar()
+ match y:
+ case 3:
+ bar()
+ case 4:
+ bar()
+ case _:
+ bar()
+`))
+
+ it("class-with-decorators", check(`
+@decorator1
+@decorator2(
+ param1,
+ param2
+)
+class MyClass:
+ def method(self):
+ pass
+`))
+
+ it("list-comprehension", check(`
+result = [
+ x * y
+ for x in range(10)
+ for y in range(5)
+ if x > y
+]
+`))
+
+ it("multi-line-expressions", check(`
+result = (
+ very_long_variable_name +
+ another_long_variable *
+ some_computation(
+ arg1,
+ arg2
+ )
+)
+`))
+
+ it("async-function-and-with", check(`
+async def process_data():
+ async with context() as ctx:
+ result = await ctx.fetch(
+ url,
+ timeout=30
+ )
+ return result
+`))
+
+ it("nested-functions", check(`
+def outer():
+ x = 1
+ def inner1():
+ y = 2
+ def inner2():
+ z = 3
+ return x + y + z
+ return inner2()
+ return inner1()
+`))
+
+ it("type-hints-and-annotations", check(`
+def process_data(
+ data: list[str],
+ config: dict[str, Any]
+) -> tuple[int, str]:
+ result: Optional[str] = None
+ if data:
+ result = data[0]
+ return len(data), result
+`))
+
+ it("multi-line-dict-comprehension", check(`
+config = {
+ key: value
+ for key, value in items
+ if is_valid(
+ key,
+ value
+ )
+}
+`))
+
+ it("multi-line-with-comments", check(`
+def process(
+ x: int, # The input value
+ y: float # The coefficient
+):
+ # Compute first step
+ result = x * y
+
+ # Apply additional processing
+ if result > 0:
+ # Positive case
+ return result
+ else:
+ # Negative case
+ return -result
+`))
+
})
From 3930ddffe73f2b7fd3e3949f25ee9ddbe3011a4b Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Sat, 18 Jan 2025 12:36:13 +0100
Subject: [PATCH 60/63] Mark version 6.1.7
---
CHANGELOG.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e0327e..ae78796 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 6.1.7 (2025-01-18)
+
+### Bug fixes
+
+Properly indent match/case statements.
+
## 6.1.6 (2024-04-29)
### Bug fixes
diff --git a/package.json b/package.json
index 5bf17ed..1215e9c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "6.1.6",
+ "version": "6.1.7",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",
From 3049f472f41c3f0c21bc9f379b55bd99b077a1e7 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Tue, 22 Apr 2025 14:53:06 +0200
Subject: [PATCH 61/63] Add code folding for multi-line strings
FEATURE: Allow multi-line strings to be code-folded.
Closes https://github.com/codemirror/dev/issues/1551
---
src/python.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/python.ts b/src/python.ts
index d4d2d65..8970c9e 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -85,7 +85,8 @@ export const pythonLanguage = LRLanguage.define({
foldNodeProp.add({
"ArrayExpression DictionaryExpression SetExpression TupleExpression": foldInside,
- Body: (node, state) => ({from: node.from + 1, to: node.to - (node.to == state.doc.length ? 0 : 1)})
+ Body: (node, state) => ({from: node.from + 1, to: node.to - (node.to == state.doc.length ? 0 : 1)}),
+ "String FormatString": (node, state) => ({from: state.doc.lineAt(node.from).to, to: node.to})
})
],
}),
From 52640ae2cf1c36dc0ad779dd92c40b318c91a8d4 Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Wed, 23 Apr 2025 14:52:46 +0200
Subject: [PATCH 62/63] Add an indentation rule for member expressions
FIX: Add an indentation rule for member expressions.
Closes 'https://github.com/codemirror/dev/issues/1553
---
src/python.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/python.ts b/src/python.ts
index 8970c9e..fa95cc5 100644
--- a/src/python.ts
+++ b/src/python.ts
@@ -76,11 +76,12 @@ export const pythonLanguage = LRLanguage.define({
"TupleExpression ComprehensionExpression ParamList ArgList ParenthesizedExpression": delimitedIndent({closing: ")"}),
"DictionaryExpression DictionaryComprehensionExpression SetExpression SetComprehensionExpression": delimitedIndent({closing: "}"}),
"ArrayExpression ArrayComprehensionExpression": delimitedIndent({closing: "]"}),
+ MemberExpression: cx => cx.baseIndent + cx.unit,
"String FormatString": () => null,
Script: context => {
let inner = innerBody(context)
return (inner && indentBody(context, inner)) ?? context.continue()
- }
+ },
}),
foldNodeProp.add({
From 34dbda2d67e9f75af4d9228b4ccd5bd7d38d12cb Mon Sep 17 00:00:00 2001
From: Marijn Haverbeke
Date: Fri, 25 Apr 2025 09:19:14 +0200
Subject: [PATCH 63/63] Mark version 6.2.0
---
CHANGELOG.md | 10 ++++++++++
package.json | 2 +-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ae78796..50f62e6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+## 6.2.0 (2025-04-25)
+
+### Bug fixes
+
+Add an indentation rule for member expressions.
+
+### New features
+
+Allow multi-line strings to be code-folded.
+
## 6.1.7 (2025-01-18)
### Bug fixes
diff --git a/package.json b/package.json
index 1215e9c..c1ae028 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@codemirror/lang-python",
- "version": "6.1.7",
+ "version": "6.2.0",
"description": "Python language support for the CodeMirror code editor",
"scripts": {
"test": "cm-runtests",