Add cancel buffer (to store cancelled operations.)

This commit is contained in:
2026-09-08 11:50:17 +01:00
parent 51676362b9
commit d6d3f31326
6 changed files with 31 additions and 19 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
#pragma once #pragma once
#include "../decl.h" #include "../decl.h"
#include "history.h" #include "readonly.h"
#include "shard.h" #include "shard.h"
namespace bed::internal::buffer { namespace bed::internal::buffer {
@@ -25,7 +25,7 @@ struct GenericBuffer : ShardBuffer {
~GenericBuffer(); ~GenericBuffer();
void list_history(BEd &ctx); void list_history(BEd &ctx);
HistoryBuffer *get_history(uint64_t version); ReadonlyBuffer *get_history(uint64_t version);
void snapshot(std::string action); void snapshot(std::string action);
bool undo(BEd &ctx); bool undo(BEd &ctx);
bool redo(BEd &ctx); bool redo(BEd &ctx);
@@ -4,36 +4,38 @@
#include "shard.h" #include "shard.h"
namespace bed::internal::buffer { namespace bed::internal::buffer {
struct HistoryBuffer : ShardBuffer { struct ReadonlyBuffer : ShardBuffer {
HistoryBuffer( bool useless = true;
ReadonlyBuffer(
std::string name, vase::Shard *root, std::string name, vase::Shard *root,
const syntax::ParserSnapshot &snapshot const syntax::ParserSnapshot &snapshot
) : ShardBuffer(std::move(name), root, snapshot, Kind::History) {} ) : ShardBuffer(std::move(name), root, snapshot, Kind::History) {}
bool waste() override { bool waste() override {
return true; return useless;
} }
void load(BEd &, vase::Shard *) override { void load(BEd &, vase::Shard *) override {
throw ed_error("History buffers are read-only."); throw ed_error("This buffer is read-only.");
} }
void set_filename(std::filesystem::path) override {} void set_filename(std::filesystem::path) override {}
std::filesystem::path filename() override { std::filesystem::path filename() override {
return {}; return {};
} }
void substitute(BEd &, uint64_t, uint64_t, std::string &, std::string &, std::string &) override { void substitute(BEd &, uint64_t, uint64_t, std::string &, std::string &, std::string &) override {
throw ed_error("History buffers are read-only."); throw ed_error("This buffer is read-only.");
} }
void join(BEd &, uint64_t, uint64_t) override { void join(BEd &, uint64_t, uint64_t) override {
throw ed_error("History buffers are read-only."); throw ed_error("This buffer is read-only.");
} }
void remove(BEd &, uint64_t, uint64_t) override { void remove(BEd &, uint64_t, uint64_t) override {
throw ed_error("History buffers are read-only."); throw ed_error("This buffer is read-only.");
} }
void append(BEd &, vase::Shard *, uint64_t) override { void append(BEd &, vase::Shard *, uint64_t) override {
throw ed_error("History buffers are read-only."); throw ed_error("This buffer is read-only.");
} }
void replace(BEd &, vase::Shard *, uint64_t, uint64_t) override { void replace(BEd &, vase::Shard *, uint64_t, uint64_t) override {
throw ed_error("History buffers are read-only."); throw ed_error("This buffer is read-only.");
} }
}; };
} // namespace bed::internal::buffer } // namespace bed::internal::buffer
+11 -2
View File
@@ -171,7 +171,14 @@ void BEd::handle(std::string_view cmd, bool eof) {
if (!b) { if (!b) {
text = a; text = a;
} else { } else {
internal::vase::Shard::release(a); if (a) {
auto p = internal::syntax::make_parser(a, a->lines + 1, lang);
auto cancel_buf = new internal::buffer::ReadonlyBuffer("cancel", a, p);
internal::syntax::release(p);
buffers["cancel"] = cancel_buf;
cancel_buf->useless = false;
internal::vase::Shard::release(a);
}
throw ed_error("Operation cancelled."); throw ed_error("Operation cancelled.");
} }
} }
@@ -194,13 +201,15 @@ void BEd::handle(std::string_view cmd, bool eof) {
internal::buffer::Buffer &BEd::buffer(const std::string &name) { internal::buffer::Buffer &BEd::buffer(const std::string &name) {
if (name.empty()) if (name.empty())
throw ed_error("can't have empty buffer name"); throw ed_error("Can't have empty buffer name");
{ {
auto it = buffers.find(name); auto it = buffers.find(name);
if (it != buffers.end()) if (it != buffers.end())
return *it->second; return *it->second;
} }
constexpr std::string_view prefix = "history/"; constexpr std::string_view prefix = "history/";
if (name == "cancel")
throw ed_error("Cancel buffer empty.");
if (name.starts_with(prefix)) { if (name.starts_with(prefix)) {
std::string_view path{name}; std::string_view path{name};
path.remove_prefix(prefix.size()); path.remove_prefix(prefix.size());
+4 -4
View File
@@ -72,21 +72,21 @@ void GenericBuffer::list_history(BEd &ctx) {
} }
} }
HistoryBuffer *GenericBuffer::get_history(uint64_t version) { ReadonlyBuffer *GenericBuffer::get_history(uint64_t version) {
uint64_t current = base_version + undo_stack.size(); uint64_t current = base_version + undo_stack.size();
if (version < base_version) if (version < base_version)
throw ed_error("History version has been pruned."); throw ed_error("History version has been pruned.");
if (version < current) { if (version < current) {
auto &item = undo_stack[version - base_version]; auto &item = undo_stack[version - base_version];
return new HistoryBuffer(name, item.text, item.parse_state); return new ReadonlyBuffer(name, item.text, item.parse_state);
} }
if (version == current) if (version == current)
return new HistoryBuffer(name, root, parse); return new ReadonlyBuffer(name, root, parse);
uint64_t redo_offset = version - current - 1; uint64_t redo_offset = version - current - 1;
if (redo_offset >= redo_stack.size()) if (redo_offset >= redo_stack.size())
throw ed_error("No such history version."); throw ed_error("No such history version.");
auto &item = redo_stack[redo_stack.size() - 1 - redo_offset]; auto &item = redo_stack[redo_stack.size() - 1 - redo_offset];
return new HistoryBuffer(name, item.text, item.parse_state); return new ReadonlyBuffer(name, item.text, item.parse_state);
} }
void GenericBuffer::snapshot(std::string action_) { void GenericBuffer::snapshot(std::string action_) {
+1
View File
@@ -188,6 +188,7 @@ void Parser::locator(AddressPromise &addr) {
token(io::Token::AddressSymbol); token(io::Token::AddressSymbol);
advance(); advance();
end_token(); end_token();
token(io::Token::Number);
addr.base = AddressPromise::Current{}; addr.base = AddressPromise::Current{};
uint16_t j = 0; uint16_t j = 0;
uint64_t num = 0; uint64_t num = 0;
+2 -2
View File
@@ -272,7 +272,7 @@ std::pair<vase::Shard *, bool> TextMode::run_terminal() {
cursor.col = byte_column(previous.line, wanted); cursor.col = byte_column(previous.line, wanted);
} break; } break;
case io::KeyEvent::SpecialKey::DOWN: { case io::KeyEvent::SpecialKey::DOWN: {
if (cursor.row + 1 >= vase->lines) if (cursor.row >= vase->lines)
break; break;
vase::Iterator current(vase, cursor.row, Direction::Forward); vase::Iterator current(vase, cursor.row, Direction::Forward);
if (!current.next()) if (!current.next())
@@ -294,7 +294,7 @@ std::pair<vase::Shard *, bool> TextMode::run_terminal() {
if (!it.next()) if (!it.next())
throw ed_error("Invalid cursor position."); throw ed_error("Invalid cursor position.");
next.col = next_cluster(it.line, cursor.col); next.col = next_cluster(it.line, cursor.col);
} else if (cursor.row + 1 < vase->lines) { } else if (cursor.row < vase->lines) {
++next.row; ++next.row;
next.col = 0; next.col = 0;
} else { } else {