#include #include #include #include #include #include #include #include #define DEFAULT_PROMPT "Bsh> " struct bshell_line_ed_shell_integration_p { struct bshell_runtime *si_rt; fx_hashtable *si_data; fx_string *si_default_prompt; bshell_pipeline *si_pipeline; bshell_cmdcall *si_prompt; }; static void init(fx_object *obj, void *priv) { struct bshell_line_ed_shell_integration_p *p = priv; p->si_default_prompt = fx_string_create_from_cstr(DEFAULT_PROMPT); p->si_pipeline = bshell_pipeline_create(); p->si_prompt = bshell_cmdcall_create(); bshell_cmdcall_push_arg(p->si_prompt, FX_CSTR("prompt")); bshell_pipeline_add_cmdcall(p->si_pipeline, p->si_prompt); } static void fini(fx_object *obj, void *priv) { struct bshell_line_ed_shell_integration_p *p = priv; bshell_pipeline_unref(p->si_pipeline); bshell_cmdcall_unref(p->si_prompt); fx_string_unref(p->si_default_prompt); } bshell_line_ed_shell_integration *bshell_line_ed_shell_integration_create( struct bshell_runtime *rt) { bshell_line_ed_shell_integration *out = fx_object_create(BSHELL_TYPE_LINE_EDITOR_SHELL_INTEGRATION); if (!out) { return NULL; } struct bshell_line_ed_shell_integration_p *p = fx_object_get_private( out, BSHELL_TYPE_LINE_EDITOR_SHELL_INTEGRATION); p->si_rt = rt; return out; } static enum bshell_status load( bshell_line_ed_plugin *plugin, bshell_line_ed *ed) { struct bshell_line_ed_shell_integration_p *shell = fx_object_get_private( plugin, BSHELL_TYPE_LINE_EDITOR_SHELL_INTEGRATION); shell->si_data = fx_hashtable_create(); struct bshell_runtime_scope *global = bshell_runtime_get_global_scope(shell->si_rt); bshell_variable *item = bshell_runtime_scope_define_variable(global, "line_editor"); bshell_variable_set_value(item, FX_VALUE_OBJECT(shell->si_data)); printf("shell integration loaded\n"); return BSHELL_SUCCESS; } static enum bshell_status get_prompt( struct bshell_line_ed_shell_integration_p *shell, bshell_line_ed *ed, fx_value *out) { enum bshell_status status = bshell_cmdcall_resolve(shell->si_prompt, shell->si_rt); if (status != BSHELL_SUCCESS) { *out = fx_value_copy_return( FX_VALUE_OBJECT(shell->si_default_prompt)); return BSHELL_SUCCESS; } int eof = 0; status = bshell_pipeline_pump_record( shell->si_pipeline, shell->si_rt, out, &eof); return status; } static enum bshell_status get_data( bshell_line_ed_plugin *plugin, bshell_line_ed *ed, const char *key, fx_value *out) { struct bshell_line_ed_shell_integration_p *shell = fx_object_get_private( plugin, BSHELL_TYPE_LINE_EDITOR_SHELL_INTEGRATION); if (!strcmp(key, "prompt")) { return get_prompt(shell, ed, out); } const fx_value *v = fx_hashtable_get(shell->si_data, &FX_CSTR(key)); if (v) { fx_value_copy(out, v); } else { *out = FX_VALUE_EMPTY; } return BSHELL_SUCCESS; } static enum bshell_status put_data( bshell_line_ed_plugin *plugin, bshell_line_ed *ed, const char *key, const fx_value *value) { if (!strcmp(key, "prompt")) { return BSHELL_SUCCESS; } struct bshell_line_ed_shell_integration_p *shell = fx_object_get_private( plugin, BSHELL_TYPE_LINE_EDITOR_SHELL_INTEGRATION); fx_hashtable_put(shell->si_data, &FX_CSTR(key), (fx_value *)value); return BSHELL_SUCCESS; } FX_TYPE_CLASS_BEGIN(bshell_line_ed_shell_integration) FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT) FX_INTERFACE_ENTRY(to_string) = NULL; FX_TYPE_VTABLE_INTERFACE_END(fx_object, FX_TYPE_OBJECT) FX_TYPE_VTABLE_INTERFACE_BEGIN( bshell_line_ed_plugin, BSHELL_TYPE_LINE_EDITOR_PLUGIN) FX_INTERFACE_ENTRY(p_load) = load; FX_INTERFACE_ENTRY(p_get_data) = get_data; FX_INTERFACE_ENTRY(p_put_data) = put_data; FX_TYPE_VTABLE_INTERFACE_END(bshell_command, BSHELL_TYPE_COMMAND) FX_TYPE_CLASS_END(bshell_line_ed_shell_integration) FX_TYPE_DEFINITION_BEGIN(bshell_line_ed_shell_integration) FX_TYPE_ID(0x8e89c8d0, 0xbc82, 0x4153, 0x9607, 0xa7a710486596); FX_TYPE_NAME("bshell.runtime.line_editor.plugins.shell_integration"); FX_TYPE_EXTENDS(BSHELL_TYPE_LINE_EDITOR_PLUGIN); FX_TYPE_CLASS(bshell_line_ed_shell_integration_class); FX_TYPE_INSTANCE_INIT(init); FX_TYPE_INSTANCE_FINI(fini); FX_TYPE_INSTANCE_PRIVATE(struct bshell_line_ed_shell_integration_p); FX_TYPE_DEFINITION_END(bshell_line_ed_shell_integration)