Add basic scripting support.

- Fix certain bugs in ruby parser
- And a lot more cleanup/minor fixes.
This commit is contained in:
2026-09-08 18:07:39 +01:00
parent a5794d9ab3
commit bb3ce7549a
20 changed files with 410 additions and 84 deletions
+3
View File
@@ -6,6 +6,7 @@
#include "internal/functions/suffixes.h"
#include "internal/io/io.h"
#include "internal/marks/marks.h"
#include "internal/scripting/ruby.h"
#include "internal/theme/theme.h"
#include "internal/ui/command.h"
#include "internal/ui/text_mode.h"
@@ -21,6 +22,8 @@ struct BEd {
std::unordered_map<std::string, internal::syntax::Language *> languages;
internal::io::IO io;
internal::vase::AppendStorage append{"/tmp"};
mrb_state *mrb = nullptr;
int arena;
bool help_mode = false;
bool prompt_mode = true;
+3 -2
View File
@@ -14,8 +14,8 @@ struct HistoryItem {
struct GenericBuffer : ShardBuffer {
uint64_t base_version{0};
std::chrono::system_clock::time_point timestamp;
std::string action;
std::chrono::system_clock::time_point timestamp{std::chrono::system_clock::now()};
std::string action{"Created buffer."};
std::filesystem::path save_path{};
std::vector<HistoryItem> undo_stack;
std::vector<HistoryItem> redo_stack;
@@ -24,6 +24,7 @@ struct GenericBuffer : ShardBuffer {
: ShardBuffer(name, nullptr, nullptr, Kind::Generic) {}
~GenericBuffer();
void language(BEd &ctx, std::string name);
void list_history(BEd &ctx);
ReadonlyBuffer *get_history(uint64_t version);
void snapshot(std::string action);
+43
View File
@@ -0,0 +1,43 @@
#pragma once
#include "definitions.h"
#include "pch.h"
namespace bed::internal::scripting {
struct Block {
mrb_value proc;
mrb_state *mrb;
Block(mrb_state *mrb, mrb_value proc)
: proc(proc), mrb(mrb) {
mrb_gc_register(mrb, proc);
}
Block() : proc(mrb_nil_value()) {}
~Block() {
if (!mrb_nil_p(proc))
mrb_gc_unregister(mrb, proc);
}
void set_proc(mrb_value new_proc) {
if (!mrb_nil_p(proc))
mrb_gc_unregister(mrb, proc);
proc = new_proc;
mrb_gc_register(mrb, proc);
}
Block(const Block &) = delete;
Block &operator=(const Block &) = delete;
mrb_value call(int argc = 0, mrb_value *argv = nullptr) const {
if (mrb_nil_p(proc))
return mrb_nil_value();
mrb_value result = mrb_funcall_argv(mrb, proc, mrb_intern_cstr(mrb, "call"), argc, argv);
return result;
}
};
void register_basic(BEd &ctx);
void run(BEd &ctx, const std::string &str);
}; // namespace bed::internal::scripting
+19 -8
View File
@@ -48,6 +48,7 @@ struct ParseState {
uint64_t line, uint64_t original, uint64_t final
);
static ParseState *concat(Language &lang, ParseState *a, ParseState *b);
static void *state_before(Language &lang, ParseState *root, vase::Shard *vase, uint64_t line);
};
struct ParseStateBranch : ParseState {
@@ -83,18 +84,25 @@ struct ParsePieceBuilder {
std::vector<ParseState *> pieces;
std::vector<uint16_t> blocks;
void *piece_state{nullptr};
void *prev_state{nullptr};
uint64_t chunk_start{0};
uint64_t chunk_lines{0};
ParsePieceBuilder(Language &lang, uint64_t first_line)
: lang(lang), chunk_start(first_line) {}
void add(
void *state,
uint64_t line,
const std::vector<ParseEvent> &events
) {
ParsePieceBuilder(Language &lang, uint64_t first_line, void *entry_state)
: lang(lang), chunk_start(first_line) {
prev_state = lang.copy(entry_state);
}
~ParsePieceBuilder() {
if (prev_state)
lang.destroy(prev_state);
if (piece_state)
lang.destroy(piece_state);
}
ParsePieceBuilder(const ParsePieceBuilder &) = delete;
ParsePieceBuilder &operator=(const ParsePieceBuilder &) = delete;
void add(void *state, uint64_t line, const std::vector<ParseEvent> &events) {
if (chunk_lines == 0) {
chunk_start = line;
piece_state = lang.copy(state);
piece_state = lang.copy(prev_state);
}
for (const auto &ev : events) {
blocks.push_back(
@@ -103,6 +111,9 @@ struct ParsePieceBuilder {
);
}
++chunk_lines;
if (prev_state)
lang.destroy(prev_state);
prev_state = lang.copy(state);
if (chunk_lines == ParseStateLeaf::MAX_CHUNK)
flush();
}
+1
View File
@@ -13,6 +13,7 @@ ParserSnapshot make_parser(vase::Shard *vase, uint64_t lines, Language *lang);
ParserSnapshot retain(const ParserSnapshot &snap);
void release(ParserSnapshot &snap);
void *state_before(const ParserSnapshot &snap, vase::Shard *vase, uint64_t line);
uint64_t next_closing(const ParserSnapshot &snap, uint64_t line);
uint64_t prev_opening(const ParserSnapshot &snap, uint64_t line);
+19
View File
@@ -4,10 +4,29 @@
#include <mruby.h>
#include <mruby/array.h>
#include <mruby/boxing_word.h>
#include <mruby/class.h>
#include <mruby/common.h>
#include <mruby/compile.h>
#include <mruby/data.h>
#include <mruby/dump.h>
#include <mruby/error.h>
#include <mruby/gc.h>
#include <mruby/hash.h>
#include <mruby/internal.h>
#include <mruby/irep.h>
#include <mruby/numeric.h>
#include <mruby/object.h>
#include <mruby/opcode.h>
#include <mruby/presym.h>
#include <mruby/proc.h>
#include <mruby/range.h>
#include <mruby/re.h>
#include <mruby/string.h>
#include <mruby/throw.h>
#include <mruby/value.h>
#include <mruby/variable.h>
#include <mruby/version.h>
#include <pcre2.h>
extern "C" {
#include <grapheme.h>