Files

161 lines
4.4 KiB
C
Raw Permalink Normal View History

#include <bshell/line-editor/line-editor.h>
#include <bshell/line-editor/plugin.h>
#include <bshell/line-editor/shell-integration.h>
#include <bshell/runtime/cmdcall.h>
#include <bshell/runtime/pipeline.h>
#include <bshell/runtime/runtime.h>
#include <bshell/runtime/scope.h>
#include <fx/term/tty.h>
#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)