import gradio as gr import pandas as pd import io import sys import traceback def init_demo(): files = { "main.py": 'print("Hello, Gradio Code Editor!")\nprint("This is a demo file.")', "app.py": 'import gradio as gr\n\ndef greet(name):\n return f"Hello, {name}!"\n\nprint("App loaded")', "utils.py": 'def utility_function():\n """A sample utility function."""\n return "Utility result"\n\nprint(utility_function())' } df_data = pd.DataFrame({"Filename": list(files.keys())}) return df_data, files, None def select_file(evt: gr.SelectData, files_state): if evt.index: filename = evt.value["Filename"] code = files_state.get(filename, "") return code, filename return "", None def add_file(new_name, files_state, df): if not new_name.strip(): raise gr.Error("Please enter a file name.") if new_name in files_state: raise gr.Error("File already exists.") files_state[new_name] = "# New file content" new_df = pd.DataFrame({"Filename": list(files_state.keys())}) return new_df, files_state def delete_file(evt: gr.SelectData, files_state, current_file_state, df): if evt.index: filename = evt.value["Filename"] del files_state[filename] new_df = pd.DataFrame({"Filename": list(files_state.keys())}) if current_file_state == filename: return new_df, files_state, None return df, files_state, current_file_state def save_file(code, current_file, files_state, df): if not current_file or current_file not in files_state: raise gr.Error("No file selected or invalid file.") files_state[current_file] = code return gr.update(value="Saved successfully!"), df, files_state def run_code(code): output = io.StringIO() old_stdout = sys.stdout old_stderr = sys.stderr sys.stdout = output sys.stderr = output g = {"__builtins__": {}} g.update(print=print, pd=pd, gr=gr, io=io, sys=sys) # Safe globals try: exec(code, g) except Exception: sys.stdout = old_stdout sys.stderr = old_stderr return traceback.format_exc() finally: sys.stdout = old_stdout sys.stderr = old_stderr return output.getvalue() custom_theme = gr.themes.Monochrome( primary_hue="blue", secondary_hue="indigo", neutral_hue="slate", font=gr.themes.GoogleFont("JetBrains Mono"), font_mono=gr.themes.GoogleFont("JetBrains Mono"), ).set( code_background_fill_dark="*neutral_900", code_token_operator_color_dark="*blue_400", code_token_constant_color_dark="*green_400", code_token_function_color_dark="*blue_400", code_token_keyword_color_dark="*purple_400", ) css = """ #left-panel { background-color: var(--neutral-900); border-right: 1px solid var(--neutral-700); overflow-y: auto; max-height: 80vh; } #right-panel { background-color: var(--neutral-925); } .monaco-editor .monaco-editor-background { background-color: #1e1e1e !important; } """ with gr.Blocks(theme=custom_theme, css=css) as demo: gr.Markdown("# Modern Code Editor") gr.Markdown("[Built with anycoder](https://huggingface.co/spaces/akhaliq/anycoder)") files_state = gr.State({}) current_file_state = gr.State(None) with gr.Row(): with gr.Column(scale=1, min_width=280, elem_id="left-panel", elem_classes="panel"): gr.Markdown("## 📁 File Explorer") files_df = gr.Dataframe( headers=["Filename"], datatype=["str"], interactive=True, wrap=False, show_row_numbers=False, max_height=300, ) gr.Markdown("### Actions") new_file_name = gr.Textbox(label="New File Name", placeholder="e.g., new_script.py") with gr.Row(): add_btn = gr.Button("➕ Add File", variant="secondary", scale=1) delete_btn = gr.Button("🗑️ Delete Selected", variant="stop", scale=1) save_btn = gr.Button("💾 Save Current File", variant="primary") status_msg = gr.Markdown("Ready", visible=False) with gr.Column(scale=4, elem_id="right-panel", elem_classes="panel"): current_file_display = gr.Markdown("**No file selected**", elem_id="current-file") editor = gr.Code( value="", language="python", lines=25, font_size="14px", show_line_numbers=True, autocomplete=True, theme="vs-dark", ) with gr.Row(): run_btn = gr.Button("▶️ Run Code", variant="primary", scale=0) output = gr.Textbox( label="Output", lines=12, max_lines=20, interactive=False, show_copy_button=True, ) # Event handlers demo.load(init_demo, outputs=[files_df, files_state, current_file_state]) files_df.select( select_file, inputs=[files_state], outputs=[editor, current_file_display], show_progress="minimal" ).then( lambda file: f"**Current: {file or 'None'}**", current_file_state, current_file_display ) add_btn.click( add_file, inputs=[new_file_name, files_state, files_df], outputs=[files_df, files_state], ) delete_btn.click( delete_file, inputs=[files_state, current_file_state, files_df], outputs=[files_df, files_state, current_file_state], ) save_btn.click( save_file, inputs=[editor, current_file_state, files_state, files_df], outputs=[status_msg, files_df, files_state], ).then( lambda: gr.update(visible=False), None, status_msg, show_progress=False ) run_btn.click( run_code, inputs=editor, outputs=output, show_progress="full", ) demo.launch( theme=custom_theme, css=css, footer_links=[{"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"}], share=False, show_error=True, enable_queue=True, )