Skip to content

Commit 731ab92

Browse files
whitphxgradio-pr-botaliabd
authored
Autocompletion on code editor component (#10733)
* Update CodeMirror packages to use the autocompletion feature of lang-python * Add autocomplete option to the Code component * add changeset * Add AutocompleteTheme * Fix test * Fix docstring * Enable autocompletion on Playground * add changeset * add changeset * Assign Tab to acceptCompletion * Enable autocompletion in the playground mode of Lite apps * add changeset --------- Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com> Co-authored-by: Ali Abdalla <ali.si3luwa@gmail.com>
1 parent 3b48367 commit 731ab92

File tree

9 files changed

+231
-184
lines changed

9 files changed

+231
-184
lines changed

.changeset/fair-socks-lead.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@gradio/code": minor
3+
"@gradio/lite": minor
4+
"gradio": minor
5+
"website": minor
6+
---
7+
8+
feat:Autocompletion on code editor component

gradio/components/code.py

+3
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ def __init__(
109109
key: int | str | None = None,
110110
wrap_lines: bool = False,
111111
show_line_numbers: bool = True,
112+
autocomplete: bool = False,
112113
):
113114
"""
114115
Parameters:
@@ -131,6 +132,7 @@ def __init__(
131132
max_lines: Maximum number of visible lines to show in the code editor. Defaults to None and will fill the height of the container.
132133
wrap_lines: If True, will wrap lines to the width of the container when overflow occurs. Defaults to False.
133134
show_line_numbers: If True, displays line numbers, and if False, hides line numbers.
135+
autocomplete: If True, will show autocomplete suggestions for supported languages. Defaults to False.
134136
"""
135137
if language not in Code.languages:
136138
raise ValueError(f"Language {language} not supported.")
@@ -140,6 +142,7 @@ def __init__(
140142
self.max_lines = max(lines, max_lines) if max_lines is not None else None
141143
self.wrap_lines = wrap_lines
142144
self.show_line_numbers = show_line_numbers
145+
self.autocomplete = autocomplete
143146
super().__init__(
144147
label=label,
145148
every=every,

js/_website/src/lib/components/DemosLite/DemosLite.svelte

+1
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@
825825
lines={10}
826826
readonly={false}
827827
dark_mode={false}
828+
autocomplete
828829
on:change={(e) => {
829830
code_state.code_edited = true;
830831
if (user_query == app_error) {

js/code/Index.svelte

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
export let min_width: number | undefined = undefined;
4141
export let wrap_lines = false;
4242
export let show_line_numbers = true;
43+
export let autocomplete = false;
4344
4445
export let interactive: boolean;
4546
@@ -93,6 +94,7 @@
9394
{dark_mode}
9495
{wrap_lines}
9596
{show_line_numbers}
97+
{autocomplete}
9698
readonly={!interactive}
9799
on:blur={() => gradio.dispatch("blur")}
98100
on:focus={() => gradio.dispatch("focus")}

js/code/package.json

+16-16
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,29 @@
77
"license": "ISC",
88
"private": false,
99
"dependencies": {
10-
"@codemirror/autocomplete": "^6.3.0",
11-
"@codemirror/commands": "^6.1.2",
12-
"@codemirror/lang-css": "^6.1.0",
13-
"@codemirror/lang-html": "^6.4.2",
14-
"@codemirror/lang-javascript": "^6.1.4",
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",
1515
"@codemirror/lang-json": "^6.0.1",
16-
"@codemirror/lang-markdown": "^6.1.0",
17-
"@codemirror/lang-python": "^6.0.4",
18-
"@codemirror/language": "^6.6.0",
19-
"@codemirror/legacy-modes": "^6.3.1",
20-
"@codemirror/lint": "^6.0.0",
21-
"@codemirror/search": "^6.2.2",
22-
"@codemirror/state": "^6.1.2",
23-
"@codemirror/view": "^6.4.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",
2424
"@gradio/atoms": "workspace:^",
2525
"@gradio/icons": "workspace:^",
2626
"@gradio/statustracker": "workspace:^",
2727
"@gradio/upload": "workspace:^",
2828
"@gradio/utils": "workspace:^",
2929
"@gradio/wasm": "workspace:^",
30-
"@lezer/common": "^1.0.2",
31-
"@lezer/highlight": "^1.1.3",
32-
"@lezer/markdown": "^1.0.2",
30+
"@lezer/common": "^1.2.3",
31+
"@lezer/highlight": "^1.2.1",
32+
"@lezer/markdown": "^1.4.2",
3333
"cm6-theme-basic-dark": "^0.2.0",
3434
"cm6-theme-basic-light": "^0.2.0",
3535
"codemirror": "^6.0.1"

js/code/shared/Code.svelte

+22-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
} from "@codemirror/view";
1010
import { StateEffect, EditorState, type Extension } from "@codemirror/state";
1111
import { indentWithTab } from "@codemirror/commands";
12+
import { autocompletion, acceptCompletion } from "@codemirror/autocomplete";
1213
1314
import { basicDark } from "cm6-theme-basic-dark";
1415
import { basicLight } from "cm6-theme-basic-light";
@@ -28,6 +29,7 @@
2829
export let placeholder: string | HTMLElement | null | undefined = undefined;
2930
export let wrap_lines = false;
3031
export let show_line_numbers = true;
32+
export let autocomplete = false;
3133
3234
const dispatch = createEventDispatcher<{
3335
change: string;
@@ -175,6 +177,19 @@
175177
}
176178
});
177179
180+
const AutocompleteTheme = EditorView.theme({
181+
".cm-tooltip-autocomplete": {
182+
"& > ul": {
183+
backgroundColor: "var(--background-fill-primary)",
184+
color: "var(--body-text-color)"
185+
},
186+
"& > ul > li[aria-selected]": {
187+
backgroundColor: "var(--color-accent-soft)",
188+
color: "var(--body-text-color)"
189+
}
190+
}
191+
});
192+
178193
function create_editor_state(_value: string | null | undefined): EditorState {
179194
return EditorState.create({
180195
doc: _value ?? undefined,
@@ -200,18 +215,23 @@
200215
extensions.push(basicSetup);
201216
}
202217
if (use_tab) {
203-
extensions.push(keymap.of([indentWithTab]));
218+
extensions.push(
219+
keymap.of([{ key: "Tab", run: acceptCompletion }, indentWithTab])
220+
);
204221
}
205222
if (placeholder) {
206223
extensions.push(placeholderExt(placeholder));
207224
}
208225
if (lang) {
209226
extensions.push(lang);
210227
}
211-
212228
if (show_line_numbers) {
213229
extensions.push(lineNumbers());
214230
}
231+
if (autocomplete) {
232+
extensions.push(autocompletion());
233+
extensions.push(AutocompleteTheme);
234+
}
215235
216236
extensions.push(EditorView.updateListener.of(handle_change));
217237
if (wrap_lines) {

js/lite/src/Playground.svelte

+1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@
146146
lines={10}
147147
readonly={!loaded}
148148
dark_mode={active_theme_mode === "dark"}
149+
autocomplete
149150
/>
150151
</Block>
151152
</div>

0 commit comments

Comments
 (0)