Make ` command behave like irb with coloring
- And `` command to run selected lines, but removing ``` as that can be done by making a new buffer and writing in that.
This commit is contained in:
@@ -120,5 +120,5 @@ struct Block {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void register_basic(BEd &ctx);
|
void register_basic(BEd &ctx);
|
||||||
void run(BEd &ctx, const std::string &str);
|
std::string run(BEd &ctx, const std::string &str);
|
||||||
}; // namespace bed::internal::scripting
|
}; // namespace bed::internal::scripting
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
register :happy, address: :none do
|
||||||
|
puts "be nice"
|
||||||
|
end
|
||||||
@@ -176,8 +176,8 @@ void Function::register_extented(BEd &ctx) {
|
|||||||
.address_kind = Function::AddressKind::Range,
|
.address_kind = Function::AddressKind::Range,
|
||||||
.argument_kind = Function::ArgumentKind::Ruby,
|
.argument_kind = Function::ArgumentKind::Ruby,
|
||||||
.input_mode = Function::InputMode::None,
|
.input_mode = Function::InputMode::None,
|
||||||
.desc = "Execute some ruby code",
|
.desc = "Execute given ruby code.",
|
||||||
.default_address = "",
|
.default_address = "0,0",
|
||||||
.accept_zero = true,
|
.accept_zero = true,
|
||||||
.pre_text_mode = nullptr,
|
.pre_text_mode = nullptr,
|
||||||
.handle = [](
|
.handle = [](
|
||||||
@@ -193,7 +193,30 @@ void Function::register_extented(BEd &ctx) {
|
|||||||
+ ";$END=" + std::to_string(addr.end)
|
+ ";$END=" + std::to_string(addr.end)
|
||||||
+ ";$BUFNAME=\"" + addr.buffername + "\"";
|
+ ";$BUFNAME=\"" + addr.buffername + "\"";
|
||||||
scripting::run(ctx, pre_code);
|
scripting::run(ctx, pre_code);
|
||||||
scripting::run(ctx, arg.cmd);
|
auto line = scripting::run(ctx, arg.cmd);
|
||||||
|
ctx.io.write("=> ", 3);
|
||||||
|
auto parser = syntax::MiniParser(
|
||||||
|
*ctx.languages["ruby"],
|
||||||
|
vase::Shard::from_string(line.data(), line.size(), true),
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
const auto &tokens = parser.lines[0].second;
|
||||||
|
uint32_t cursor = 0;
|
||||||
|
for (const auto &token : tokens) {
|
||||||
|
const uint32_t start = token.start;
|
||||||
|
const uint32_t end = token.end;
|
||||||
|
if (start > line.size() || end > line.size())
|
||||||
|
break;
|
||||||
|
if (cursor < start)
|
||||||
|
ctx.io.write(line.data() + cursor, start - cursor);
|
||||||
|
ctx.io.apply(token.type);
|
||||||
|
ctx.io.write(line.data() + start, end - start);
|
||||||
|
ctx.io.reset();
|
||||||
|
cursor = end;
|
||||||
|
}
|
||||||
|
if (cursor < line.size())
|
||||||
|
ctx.io.write(line.data() + cursor, line.size() - cursor);
|
||||||
|
ctx.io.write_line("");
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -204,7 +227,7 @@ void Function::register_extented(BEd &ctx) {
|
|||||||
.argument_kind = Function::ArgumentKind::None,
|
.argument_kind = Function::ArgumentKind::None,
|
||||||
.input_mode = Function::InputMode::None,
|
.input_mode = Function::InputMode::None,
|
||||||
.desc = "Execute addressed lines as ruby code.",
|
.desc = "Execute addressed lines as ruby code.",
|
||||||
.default_address = ".,.",
|
.default_address = "1,$",
|
||||||
.accept_zero = false,
|
.accept_zero = false,
|
||||||
.pre_text_mode = nullptr,
|
.pre_text_mode = nullptr,
|
||||||
.handle = [](
|
.handle = [](
|
||||||
@@ -230,38 +253,6 @@ void Function::register_extented(BEd &ctx) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
ctx.functions.insert(
|
|
||||||
"```",
|
|
||||||
Function{
|
|
||||||
.address_kind = Function::AddressKind::Range,
|
|
||||||
.argument_kind = Function::ArgumentKind::None,
|
|
||||||
.input_mode = Function::InputMode::Text,
|
|
||||||
.desc = "Execute some ruby code (taken from text mode)",
|
|
||||||
.default_address = "",
|
|
||||||
.accept_zero = true,
|
|
||||||
.pre_text_mode = [](
|
|
||||||
BEd &ctx,
|
|
||||||
const buffer::Address &,
|
|
||||||
const Argument &
|
|
||||||
) -> std::tuple<vase::Shard *, syntax::Language *, void *> {
|
|
||||||
return {nullptr, ctx.languages["ruby"], nullptr};
|
|
||||||
},
|
|
||||||
.handle = [](
|
|
||||||
BEd &ctx,
|
|
||||||
const buffer::Address &addr_,
|
|
||||||
vase::Shard *code,
|
|
||||||
const Argument &,
|
|
||||||
std::vector<buffer::Line> *
|
|
||||||
) {
|
|
||||||
auto &addr = std::get<buffer::Range>(addr_);
|
|
||||||
auto pre_code = "$START=" + std::to_string(addr.start)
|
|
||||||
+ ";$END=" + std::to_string(addr.end)
|
|
||||||
+ ";$BUFNAME=\"" + addr.buffername + "\"";
|
|
||||||
scripting::run(ctx, pre_code);
|
|
||||||
scripting::run(ctx, vase::to_string(code));
|
|
||||||
vase::Shard::release(code); },
|
|
||||||
}
|
|
||||||
);
|
|
||||||
ctx.functions.insert(
|
ctx.functions.insert(
|
||||||
"echo",
|
"echo",
|
||||||
Function{
|
Function{
|
||||||
|
|||||||
@@ -115,11 +115,14 @@ void register_basic(BEd &ctx) {
|
|||||||
mrb_define_method(mrb, mrb->kernel_module, "unregister", mrb_bed_unregister, MRB_ARGS_REQ(1));
|
mrb_define_method(mrb, mrb->kernel_module, "unregister", mrb_bed_unregister, MRB_ARGS_REQ(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(BEd &ctx, const std::string &str) {
|
std::string run(BEd &ctx, const std::string &str) {
|
||||||
mrb_state *mrb = ctx.mrb.state;
|
mrb_state *mrb = ctx.mrb.state;
|
||||||
mrb_load_nstring(mrb, str.data(), str.size());
|
mrb_value result = mrb_load_nstring(mrb, str.data(), str.size());
|
||||||
if (!mrb->exc)
|
if (!mrb->exc) {
|
||||||
return;
|
mrb_value inspected = mrb_funcall(mrb, result, "inspect", 0);
|
||||||
|
std::string output(RSTRING_PTR(inspected), RSTRING_LEN(inspected));
|
||||||
|
return output;
|
||||||
|
}
|
||||||
mrb_value exc = mrb_obj_value(mrb->exc);
|
mrb_value exc = mrb_obj_value(mrb->exc);
|
||||||
mrb_value msg = mrb_funcall(mrb, exc, "message", 0);
|
mrb_value msg = mrb_funcall(mrb, exc, "message", 0);
|
||||||
std::string error;
|
std::string error;
|
||||||
|
|||||||
Reference in New Issue
Block a user