@gradio/code 0.11.2 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/Index.svelte +2 -0
- package/dist/Index.svelte +2 -0
- package/dist/Index.svelte.d.ts +1 -0
- package/dist/shared/Code.svelte +29 -1
- package/dist/shared/Code.svelte.d.ts +1 -0
- package/dist/shared/autocomplete.d.ts +4 -0
- package/dist/shared/autocomplete.js +49 -0
- package/dist/shared/language.js +0 -18
- package/package.json +21 -21
- package/shared/Code.svelte +35 -2
- package/shared/autocomplete.ts +63 -0
- package/shared/language.ts +0 -19
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,30 @@
|
|
1
1
|
# @gradio/code
|
2
2
|
|
3
|
+
## 0.13.0
|
4
|
+
|
5
|
+
### Features
|
6
|
+
|
7
|
+
- [#10812](https://github.com/gradio-app/gradio/pull/10812) [`6384bcc`](https://github.com/gradio-app/gradio/commit/6384bcc11f13d22f4480e7ad7213486fecec8936) - Jedi-based Python code completion on `gr.Code`. Thanks @whitphx!
|
8
|
+
|
9
|
+
### Dependency updates
|
10
|
+
|
11
|
+
- @gradio/atoms@0.14.1
|
12
|
+
- @gradio/statustracker@0.10.6
|
13
|
+
- @gradio/wasm@0.18.0
|
14
|
+
- @gradio/upload@0.15.6
|
15
|
+
|
16
|
+
## 0.12.0
|
17
|
+
|
18
|
+
### Features
|
19
|
+
|
20
|
+
- [#10733](https://github.com/gradio-app/gradio/pull/10733) [`731ab92`](https://github.com/gradio-app/gradio/commit/731ab92001c88d4cf1062acf0a4f1108a4513014) - Autocompletion on code editor component. Thanks @whitphx!
|
21
|
+
|
22
|
+
### Dependency updates
|
23
|
+
|
24
|
+
- @gradio/upload@0.15.5
|
25
|
+
- @gradio/statustracker@0.10.5
|
26
|
+
- @gradio/atoms@0.14.0
|
27
|
+
|
3
28
|
## 0.11.2
|
4
29
|
|
5
30
|
### Dependency updates
|
package/Index.svelte
CHANGED
@@ -40,6 +40,7 @@
|
|
40
40
|
export let min_width: number | undefined = undefined;
|
41
41
|
export let wrap_lines = false;
|
42
42
|
export let show_line_numbers = true;
|
43
|
+
export let autocomplete = false;
|
43
44
|
|
44
45
|
export let interactive: boolean;
|
45
46
|
|
@@ -93,6 +94,7 @@
|
|
93
94
|
{dark_mode}
|
94
95
|
{wrap_lines}
|
95
96
|
{show_line_numbers}
|
97
|
+
{autocomplete}
|
96
98
|
readonly={!interactive}
|
97
99
|
on:blur={() => gradio.dispatch("blur")}
|
98
100
|
on:focus={() => gradio.dispatch("focus")}
|
package/dist/Index.svelte
CHANGED
@@ -27,6 +27,7 @@ export let scale = null;
|
|
27
27
|
export let min_width = void 0;
|
28
28
|
export let wrap_lines = false;
|
29
29
|
export let show_line_numbers = true;
|
30
|
+
export let autocomplete = false;
|
30
31
|
export let interactive;
|
31
32
|
let dark_mode = gradio.theme === "dark";
|
32
33
|
function handle_change() {
|
@@ -78,6 +79,7 @@ $:
|
|
78
79
|
{dark_mode}
|
79
80
|
{wrap_lines}
|
80
81
|
{show_line_numbers}
|
82
|
+
{autocomplete}
|
81
83
|
readonly={!interactive}
|
82
84
|
on:blur={() => gradio.dispatch("blur")}
|
83
85
|
on:focus={() => gradio.dispatch("focus")}
|
package/dist/Index.svelte.d.ts
CHANGED
package/dist/shared/Code.svelte
CHANGED
@@ -8,10 +8,13 @@ import {
|
|
8
8
|
} from "@codemirror/view";
|
9
9
|
import { StateEffect, EditorState } from "@codemirror/state";
|
10
10
|
import { indentWithTab } from "@codemirror/commands";
|
11
|
+
import { autocompletion, acceptCompletion } from "@codemirror/autocomplete";
|
12
|
+
import { LanguageSupport } from "@codemirror/language";
|
11
13
|
import { basicDark } from "cm6-theme-basic-dark";
|
12
14
|
import { basicLight } from "cm6-theme-basic-light";
|
13
15
|
import { basicSetup } from "./extensions";
|
14
16
|
import { getLanguageExtension } from "./language";
|
17
|
+
import { create_pyodide_autocomplete } from "./autocomplete";
|
15
18
|
export let class_names = "";
|
16
19
|
export let value = "";
|
17
20
|
export let dark_mode;
|
@@ -25,14 +28,21 @@ export let readonly = false;
|
|
25
28
|
export let placeholder = void 0;
|
26
29
|
export let wrap_lines = false;
|
27
30
|
export let show_line_numbers = true;
|
31
|
+
export let autocomplete = false;
|
28
32
|
const dispatch = createEventDispatcher();
|
29
33
|
let lang_extension;
|
30
34
|
let element;
|
31
35
|
let view;
|
32
36
|
$:
|
33
37
|
get_lang(language);
|
38
|
+
const pyodide_autocomplete = create_pyodide_autocomplete();
|
34
39
|
async function get_lang(val) {
|
35
40
|
const ext = await getLanguageExtension(val);
|
41
|
+
if (pyodide_autocomplete && val === "python" && ext instanceof LanguageSupport) {
|
42
|
+
ext.support.push(
|
43
|
+
ext.language.data.of({ autocomplete: pyodide_autocomplete })
|
44
|
+
);
|
45
|
+
}
|
36
46
|
lang_extension = ext;
|
37
47
|
}
|
38
48
|
$:
|
@@ -156,6 +166,18 @@ const FontTheme = EditorView.theme({
|
|
156
166
|
borderLeftColor: "var(--body-text-color)"
|
157
167
|
}
|
158
168
|
});
|
169
|
+
const AutocompleteTheme = EditorView.theme({
|
170
|
+
".cm-tooltip-autocomplete": {
|
171
|
+
"& > ul": {
|
172
|
+
backgroundColor: "var(--background-fill-primary)",
|
173
|
+
color: "var(--body-text-color)"
|
174
|
+
},
|
175
|
+
"& > ul > li[aria-selected]": {
|
176
|
+
backgroundColor: "var(--color-accent-soft)",
|
177
|
+
color: "var(--body-text-color)"
|
178
|
+
}
|
179
|
+
}
|
180
|
+
});
|
159
181
|
function create_editor_state(_value) {
|
160
182
|
return EditorState.create({
|
161
183
|
doc: _value ?? void 0,
|
@@ -172,7 +194,9 @@ function get_base_extensions(basic2, use_tab2, placeholder2, readonly2, lang, sh
|
|
172
194
|
extensions2.push(basicSetup);
|
173
195
|
}
|
174
196
|
if (use_tab2) {
|
175
|
-
extensions2.push(
|
197
|
+
extensions2.push(
|
198
|
+
keymap.of([{ key: "Tab", run: acceptCompletion }, indentWithTab])
|
199
|
+
);
|
176
200
|
}
|
177
201
|
if (placeholder2) {
|
178
202
|
extensions2.push(placeholderExt(placeholder2));
|
@@ -183,6 +207,10 @@ function get_base_extensions(basic2, use_tab2, placeholder2, readonly2, lang, sh
|
|
183
207
|
if (show_line_numbers2) {
|
184
208
|
extensions2.push(lineNumbers());
|
185
209
|
}
|
210
|
+
if (autocomplete) {
|
211
|
+
extensions2.push(autocompletion());
|
212
|
+
extensions2.push(AutocompleteTheme);
|
213
|
+
}
|
186
214
|
extensions2.push(EditorView.updateListener.of(handle_change));
|
187
215
|
if (wrap_lines) {
|
188
216
|
extensions2.push(EditorView.lineWrapping);
|
@@ -0,0 +1,4 @@
|
|
1
|
+
import type { CompletionContext, CompletionResult } from "@codemirror/autocomplete";
|
2
|
+
type CodeMirrorAutocompleteAsyncFn = (context: CompletionContext) => Promise<CompletionResult | null>;
|
3
|
+
export declare function create_pyodide_autocomplete(): CodeMirrorAutocompleteAsyncFn | null;
|
4
|
+
export {};
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import { getWorkerProxyContext } from "@gradio/wasm/svelte";
|
2
|
+
// Jedi's completion types to CodeMirror's completion types.
|
3
|
+
// If not defined here, Jedi's completion types will be used.
|
4
|
+
const completion_type_map = {
|
5
|
+
module: "namespace"
|
6
|
+
};
|
7
|
+
export function create_pyodide_autocomplete() {
|
8
|
+
let maybe_worker_proxy;
|
9
|
+
try {
|
10
|
+
maybe_worker_proxy = getWorkerProxyContext();
|
11
|
+
}
|
12
|
+
catch (e) {
|
13
|
+
console.debug("Not in the Wasm env. Context-aware autocomplete disabled.");
|
14
|
+
return null;
|
15
|
+
}
|
16
|
+
if (!maybe_worker_proxy) {
|
17
|
+
return null;
|
18
|
+
}
|
19
|
+
const worker_proxy = maybe_worker_proxy;
|
20
|
+
return async function pyodide_autocomplete(context) {
|
21
|
+
try {
|
22
|
+
const completions = await worker_proxy.getCodeCompletions({
|
23
|
+
code: context.state.doc.toString(),
|
24
|
+
line: context.state.doc.lineAt(context.state.selection.main.head)
|
25
|
+
.number,
|
26
|
+
column: context.state.selection.main.head -
|
27
|
+
context.state.doc.lineAt(context.state.selection.main.head).from
|
28
|
+
});
|
29
|
+
if (completions.length === 0) {
|
30
|
+
return null;
|
31
|
+
}
|
32
|
+
return {
|
33
|
+
from: context.state.selection.main.head -
|
34
|
+
completions[0].completion_prefix_length,
|
35
|
+
options: completions.map((completion) => ({
|
36
|
+
label: completion.label,
|
37
|
+
type: completion_type_map[completion.type] ?? completion.type,
|
38
|
+
documentation: completion.docstring,
|
39
|
+
// Items starting with "_" are private attributes and should be sorted last.
|
40
|
+
boost: completion.label.startsWith("_") ? -1 : 0
|
41
|
+
}))
|
42
|
+
};
|
43
|
+
}
|
44
|
+
catch (e) {
|
45
|
+
console.error("Error getting completions", e);
|
46
|
+
return null;
|
47
|
+
}
|
48
|
+
};
|
49
|
+
}
|
package/dist/shared/language.js
CHANGED
@@ -1,23 +1,5 @@
|
|
1
1
|
import { StreamLanguage } from "@codemirror/language";
|
2
|
-
import { sql } from "@codemirror/legacy-modes/mode/sql";
|
3
2
|
import { _ } from "svelte-i18n";
|
4
|
-
const possible_langs = [
|
5
|
-
"python",
|
6
|
-
"c",
|
7
|
-
"cpp",
|
8
|
-
"markdown",
|
9
|
-
"json",
|
10
|
-
"html",
|
11
|
-
"css",
|
12
|
-
"javascript",
|
13
|
-
"jinja2",
|
14
|
-
"typescript",
|
15
|
-
"yaml",
|
16
|
-
"dockerfile",
|
17
|
-
"shell",
|
18
|
-
"r",
|
19
|
-
"sql"
|
20
|
-
];
|
21
3
|
const sql_dialects = [
|
22
4
|
"standardSQL",
|
23
5
|
"msSQL",
|
package/package.json
CHANGED
@@ -1,38 +1,38 @@
|
|
1
1
|
{
|
2
2
|
"name": "@gradio/code",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.13.0",
|
4
4
|
"description": "Gradio UI packages",
|
5
5
|
"type": "module",
|
6
6
|
"author": "",
|
7
7
|
"license": "ISC",
|
8
8
|
"private": false,
|
9
9
|
"dependencies": {
|
10
|
-
"@codemirror/autocomplete": "^6.
|
11
|
-
"@codemirror/commands": "^6.
|
12
|
-
"@codemirror/lang-css": "^6.1
|
13
|
-
"@codemirror/lang-html": "^6.4.
|
14
|
-
"@codemirror/lang-javascript": "^6.
|
10
|
+
"@codemirror/autocomplete": "^6.18.6",
|
11
|
+
"@codemirror/commands": "^6.8.0",
|
12
|
+
"@codemirror/lang-css": "^6.3.1",
|
13
|
+
"@codemirror/lang-html": "^6.4.9",
|
14
|
+
"@codemirror/lang-javascript": "^6.2.3",
|
15
15
|
"@codemirror/lang-json": "^6.0.1",
|
16
|
-
"@codemirror/lang-markdown": "^6.
|
17
|
-
"@codemirror/lang-python": "^6.
|
18
|
-
"@codemirror/language": "^6.
|
19
|
-
"@codemirror/legacy-modes": "^6.3
|
20
|
-
"@codemirror/lint": "^6.
|
21
|
-
"@codemirror/search": "^6.
|
22
|
-
"@codemirror/state": "^6.
|
23
|
-
"@codemirror/view": "^6.
|
24
|
-
"@lezer/common": "^1.
|
25
|
-
"@lezer/highlight": "^1.1
|
26
|
-
"@lezer/markdown": "^1.
|
16
|
+
"@codemirror/lang-markdown": "^6.3.2",
|
17
|
+
"@codemirror/lang-python": "^6.1.7",
|
18
|
+
"@codemirror/language": "^6.10.8",
|
19
|
+
"@codemirror/legacy-modes": "^6.4.3",
|
20
|
+
"@codemirror/lint": "^6.8.4",
|
21
|
+
"@codemirror/search": "^6.5.10",
|
22
|
+
"@codemirror/state": "^6.5.2",
|
23
|
+
"@codemirror/view": "^6.36.3",
|
24
|
+
"@lezer/common": "^1.2.3",
|
25
|
+
"@lezer/highlight": "^1.2.1",
|
26
|
+
"@lezer/markdown": "^1.4.2",
|
27
27
|
"cm6-theme-basic-dark": "^0.2.0",
|
28
28
|
"cm6-theme-basic-light": "^0.2.0",
|
29
29
|
"codemirror": "^6.0.1",
|
30
|
-
"@gradio/atoms": "^0.
|
30
|
+
"@gradio/atoms": "^0.14.1",
|
31
|
+
"@gradio/statustracker": "^0.10.6",
|
31
32
|
"@gradio/icons": "^0.10.0",
|
32
|
-
"@gradio/upload": "^0.15.4",
|
33
|
-
"@gradio/statustracker": "^0.10.4",
|
34
33
|
"@gradio/utils": "^0.10.1",
|
35
|
-
"@gradio/
|
34
|
+
"@gradio/upload": "^0.15.6",
|
35
|
+
"@gradio/wasm": "^0.18.0"
|
36
36
|
},
|
37
37
|
"main_changeset": true,
|
38
38
|
"main": "./Index.svelte",
|
package/shared/Code.svelte
CHANGED
@@ -9,11 +9,14 @@
|
|
9
9
|
} from "@codemirror/view";
|
10
10
|
import { StateEffect, EditorState, type Extension } from "@codemirror/state";
|
11
11
|
import { indentWithTab } from "@codemirror/commands";
|
12
|
+
import { autocompletion, acceptCompletion } from "@codemirror/autocomplete";
|
13
|
+
import { LanguageSupport } from "@codemirror/language";
|
12
14
|
|
13
15
|
import { basicDark } from "cm6-theme-basic-dark";
|
14
16
|
import { basicLight } from "cm6-theme-basic-light";
|
15
17
|
import { basicSetup } from "./extensions";
|
16
18
|
import { getLanguageExtension } from "./language";
|
19
|
+
import { create_pyodide_autocomplete } from "./autocomplete";
|
17
20
|
|
18
21
|
export let class_names = "";
|
19
22
|
export let value = "";
|
@@ -28,6 +31,7 @@
|
|
28
31
|
export let placeholder: string | HTMLElement | null | undefined = undefined;
|
29
32
|
export let wrap_lines = false;
|
30
33
|
export let show_line_numbers = true;
|
34
|
+
export let autocomplete = false;
|
31
35
|
|
32
36
|
const dispatch = createEventDispatcher<{
|
33
37
|
change: string;
|
@@ -40,8 +44,19 @@
|
|
40
44
|
|
41
45
|
$: get_lang(language);
|
42
46
|
|
47
|
+
const pyodide_autocomplete = create_pyodide_autocomplete();
|
48
|
+
|
43
49
|
async function get_lang(val: string): Promise<void> {
|
44
50
|
const ext = await getLanguageExtension(val);
|
51
|
+
if (
|
52
|
+
pyodide_autocomplete &&
|
53
|
+
val === "python" &&
|
54
|
+
ext instanceof LanguageSupport
|
55
|
+
) {
|
56
|
+
(ext.support as Extension[]).push(
|
57
|
+
ext.language.data.of({ autocomplete: pyodide_autocomplete })
|
58
|
+
);
|
59
|
+
}
|
45
60
|
lang_extension = ext;
|
46
61
|
}
|
47
62
|
|
@@ -175,6 +190,19 @@
|
|
175
190
|
}
|
176
191
|
});
|
177
192
|
|
193
|
+
const AutocompleteTheme = EditorView.theme({
|
194
|
+
".cm-tooltip-autocomplete": {
|
195
|
+
"& > ul": {
|
196
|
+
backgroundColor: "var(--background-fill-primary)",
|
197
|
+
color: "var(--body-text-color)"
|
198
|
+
},
|
199
|
+
"& > ul > li[aria-selected]": {
|
200
|
+
backgroundColor: "var(--color-accent-soft)",
|
201
|
+
color: "var(--body-text-color)"
|
202
|
+
}
|
203
|
+
}
|
204
|
+
});
|
205
|
+
|
178
206
|
function create_editor_state(_value: string | null | undefined): EditorState {
|
179
207
|
return EditorState.create({
|
180
208
|
doc: _value ?? undefined,
|
@@ -200,7 +228,9 @@
|
|
200
228
|
extensions.push(basicSetup);
|
201
229
|
}
|
202
230
|
if (use_tab) {
|
203
|
-
extensions.push(
|
231
|
+
extensions.push(
|
232
|
+
keymap.of([{ key: "Tab", run: acceptCompletion }, indentWithTab])
|
233
|
+
);
|
204
234
|
}
|
205
235
|
if (placeholder) {
|
206
236
|
extensions.push(placeholderExt(placeholder));
|
@@ -208,10 +238,13 @@
|
|
208
238
|
if (lang) {
|
209
239
|
extensions.push(lang);
|
210
240
|
}
|
211
|
-
|
212
241
|
if (show_line_numbers) {
|
213
242
|
extensions.push(lineNumbers());
|
214
243
|
}
|
244
|
+
if (autocomplete) {
|
245
|
+
extensions.push(autocompletion());
|
246
|
+
extensions.push(AutocompleteTheme);
|
247
|
+
}
|
215
248
|
|
216
249
|
extensions.push(EditorView.updateListener.of(handle_change));
|
217
250
|
if (wrap_lines) {
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import type {
|
2
|
+
CompletionContext,
|
3
|
+
CompletionResult
|
4
|
+
} from "@codemirror/autocomplete";
|
5
|
+
import { getWorkerProxyContext } from "@gradio/wasm/svelte";
|
6
|
+
import type { WorkerProxy } from "@gradio/wasm";
|
7
|
+
|
8
|
+
// Jedi's completion types to CodeMirror's completion types.
|
9
|
+
// If not defined here, Jedi's completion types will be used.
|
10
|
+
const completion_type_map: Record<string, string> = {
|
11
|
+
module: "namespace"
|
12
|
+
};
|
13
|
+
|
14
|
+
type CodeMirrorAutocompleteAsyncFn = (
|
15
|
+
context: CompletionContext
|
16
|
+
) => Promise<CompletionResult | null>;
|
17
|
+
|
18
|
+
export function create_pyodide_autocomplete(): CodeMirrorAutocompleteAsyncFn | null {
|
19
|
+
let maybe_worker_proxy: WorkerProxy | undefined;
|
20
|
+
try {
|
21
|
+
maybe_worker_proxy = getWorkerProxyContext();
|
22
|
+
} catch (e) {
|
23
|
+
console.debug("Not in the Wasm env. Context-aware autocomplete disabled.");
|
24
|
+
return null;
|
25
|
+
}
|
26
|
+
if (!maybe_worker_proxy) {
|
27
|
+
return null;
|
28
|
+
}
|
29
|
+
const worker_proxy = maybe_worker_proxy;
|
30
|
+
|
31
|
+
return async function pyodide_autocomplete(
|
32
|
+
context: CompletionContext
|
33
|
+
): Promise<CompletionResult | null> {
|
34
|
+
try {
|
35
|
+
const completions = await worker_proxy.getCodeCompletions({
|
36
|
+
code: context.state.doc.toString(),
|
37
|
+
line: context.state.doc.lineAt(context.state.selection.main.head)
|
38
|
+
.number,
|
39
|
+
column:
|
40
|
+
context.state.selection.main.head -
|
41
|
+
context.state.doc.lineAt(context.state.selection.main.head).from
|
42
|
+
});
|
43
|
+
if (completions.length === 0) {
|
44
|
+
return null;
|
45
|
+
}
|
46
|
+
return {
|
47
|
+
from:
|
48
|
+
context.state.selection.main.head -
|
49
|
+
completions[0].completion_prefix_length,
|
50
|
+
options: completions.map((completion) => ({
|
51
|
+
label: completion.label,
|
52
|
+
type: completion_type_map[completion.type] ?? completion.type,
|
53
|
+
documentation: completion.docstring,
|
54
|
+
// Items starting with "_" are private attributes and should be sorted last.
|
55
|
+
boost: completion.label.startsWith("_") ? -1 : 0
|
56
|
+
}))
|
57
|
+
};
|
58
|
+
} catch (e) {
|
59
|
+
console.error("Error getting completions", e);
|
60
|
+
return null;
|
61
|
+
}
|
62
|
+
};
|
63
|
+
}
|
package/shared/language.ts
CHANGED
@@ -1,26 +1,7 @@
|
|
1
1
|
import type { Extension } from "@codemirror/state";
|
2
2
|
import { StreamLanguage } from "@codemirror/language";
|
3
|
-
import { sql } from "@codemirror/legacy-modes/mode/sql";
|
4
3
|
import { _ } from "svelte-i18n";
|
5
4
|
|
6
|
-
const possible_langs = [
|
7
|
-
"python",
|
8
|
-
"c",
|
9
|
-
"cpp",
|
10
|
-
"markdown",
|
11
|
-
"json",
|
12
|
-
"html",
|
13
|
-
"css",
|
14
|
-
"javascript",
|
15
|
-
"jinja2",
|
16
|
-
"typescript",
|
17
|
-
"yaml",
|
18
|
-
"dockerfile",
|
19
|
-
"shell",
|
20
|
-
"r",
|
21
|
-
"sql"
|
22
|
-
];
|
23
|
-
|
24
5
|
const sql_dialects = [
|
25
6
|
"standardSQL",
|
26
7
|
"msSQL",
|