diff --git a/include/bed.h b/include/bed.h index 553cbda..7bd3001 100644 --- a/include/bed.h +++ b/include/bed.h @@ -34,7 +34,8 @@ struct BEd { std::unordered_map buffers; - internal::buffer::Range prev; + internal::buffer::Range prev_1; + internal::buffer::Range prev_2; internal::marks::MarksEngine marks; BEd(std::vector args, internal::io::IO &io); @@ -42,6 +43,7 @@ struct BEd { internal::buffer::Buffer &buffer(const std::string &); internal::buffer::Line ¤t(); + internal::buffer::Range &prev(); void mark(char, internal::buffer::Line); void handle(std::string_view cmd, bool eof); diff --git a/src/bed/run.cc b/src/bed/run.cc index 7903a3c..1990454 100644 --- a/src/bed/run.cc +++ b/src/bed/run.cc @@ -67,6 +67,7 @@ void BEd::handle(std::string_view cmd, bool eof) { internal::parser::Command c = internal::parser::Parser::get_command(cmd, *this); if (c.temp_address) { marks.get(251) = marks.get(250); + prev_2 = prev_1; temporary_current = true; } internal::buffer::Address address; @@ -165,6 +166,13 @@ internal::buffer::Line &BEd::current() { return marks.get(250 + temporary_current); } +internal::buffer::Range &BEd::prev() { + if (temporary_current) + return prev_2; + else + return prev_1; +} + void BEd::mark(char m, internal::buffer::Line line) { marks.get(m) = line; } diff --git a/src/internal/buffer/buffer.cc b/src/internal/buffer/buffer.cc index 9e66a6a..1794ade 100644 --- a/src/internal/buffer/buffer.cc +++ b/src/internal/buffer/buffer.cc @@ -35,21 +35,21 @@ void Buffer::load(BEd &, vase::Shard *text) { } void Buffer::append(BEd &ctx, vase::Shard *text, uint64_t line) { - ctx.prev.buffername = name; - ctx.prev.start = line + 1; - ctx.prev.end = line + text->lines + 1; + ctx.prev().buffername = name; + ctx.prev().start = line + 1; + ctx.prev().end = line + text->lines + 1; root = vase::insert(&ctx.append, root, text, line); - ctx.marks.insert(name, ctx.prev.start, ctx.prev.end); + ctx.marks.insert(name, ctx.prev().start, ctx.prev().end); if (parser) - parser->insert(root, ctx.prev.start, ctx.prev.end); + parser->insert(root, ctx.prev().start, ctx.prev().end); state = Modified; } void Buffer::remove(BEd &ctx, uint64_t start_line, uint64_t end_line) { root = vase::erase(root, start_line, end_line); - ctx.prev.buffername = name; - ctx.prev.start = lines() ? 1 : 0; - ctx.prev.end = lines(); + ctx.prev().buffername = name; + ctx.prev().start = lines() ? 1 : 0; + ctx.prev().end = lines(); ctx.marks.erase(name, start_line, end_line - start_line + 1); if (parser) parser->erase(root, start_line, end_line - start_line + 1); @@ -58,9 +58,9 @@ void Buffer::remove(BEd &ctx, uint64_t start_line, uint64_t end_line) { void Buffer::join(BEd &ctx, uint64_t start_line, uint64_t end_line) { root = vase::join(root, start_line, end_line); - ctx.prev.buffername = name; - ctx.prev.start = start_line; - ctx.prev.end = start_line; + ctx.prev().buffername = name; + ctx.prev().start = start_line; + ctx.prev().end = start_line; ctx.marks.collapse(name, start_line, end_line - start_line); if (parser) parser->erase(root, start_line, end_line - start_line); @@ -118,9 +118,9 @@ inline void reset(std::ostream &out) { } void Buffer::print(BEd &ctx, uint64_t start_line, uint64_t end_line) { - ctx.prev.buffername = name; - ctx.prev.start = start_line; - ctx.prev.end = end_line; + ctx.prev().buffername = name; + ctx.prev().start = start_line; + ctx.prev().end = end_line; if (parser) { std::optional it_o = parser->get_hl(root, start_line - 1); auto &it = *it_o; @@ -161,9 +161,9 @@ void Buffer::print(BEd &ctx, uint64_t start_line, uint64_t end_line) { } void Buffer::number_print(BEd &ctx, uint64_t start_line, uint64_t end_line) { - ctx.prev.buffername = name; - ctx.prev.start = start_line; - ctx.prev.end = end_line; + ctx.prev().buffername = name; + ctx.prev().start = start_line; + ctx.prev().end = end_line; uint8_t width = 1; for (uint64_t n = end_line; n >= 10; n /= 10) ++width; diff --git a/src/internal/functions/functions.cc b/src/internal/functions/functions.cc index 5400b90..28e4239 100644 --- a/src/internal/functions/functions.cc +++ b/src/internal/functions/functions.cc @@ -66,11 +66,28 @@ void Function::register_posix(BEd &ctx) { .handle = [](BEd &ctx, const buffer::Address &addr_, vase::Shard *text, const Argument &, std::vector *) { auto addr = std::get(addr_); ctx.buffer(addr.buffername).append(ctx, text, addr.number); - ctx.current() = {ctx.prev.buffername, ctx.prev.end}; + ctx.current() = {ctx.prev().buffername, ctx.prev().end}; vase::Shard::release(text); } } ); + ctx.functions.insert( + "d", + Function{ + .address_kind = Function::AddressKind::Range, + .argument_kind = Function::ArgumentKind::None, + .input_mode = Function::InputMode::None, + .desc = "Delete set of lines.", + .default_address = ".,.", + .accept_zero = true, + .pre_text_mode = nullptr, + .handle = [](BEd &ctx, const buffer::Address &addr_, vase::Shard *, const Argument &, std::vector *) { + auto addr = std::get(addr_); + ctx.buffer(addr.buffername).remove(ctx, addr.start, addr.end); + ctx.current() = {addr.buffername, addr.start}; + } + } + ); ctx.functions.insert( "j", Function{ diff --git a/src/internal/parser/address_promise.cc b/src/internal/parser/address_promise.cc index 1d5942a..27971d1 100644 --- a/src/internal/parser/address_promise.cc +++ b/src/internal/parser/address_promise.cc @@ -119,8 +119,8 @@ std::optional AddressPromise::get_line(BEd &ctx, std::vector(curr.base)) { - curr.bufname = ctx.prev.buffername; - curr.base = Number(ctx.prev.end); + curr.bufname = ctx.prev().buffername; + curr.base = Number(ctx.prev().end); prev_given = true; } else { prev_given = true; @@ -146,8 +146,8 @@ std::optional AddressPromise::get_line(BEd &ctx, std::vector(curr.base)) { - curr.bufname = ctx.prev.buffername; - curr.base = Number(ctx.prev.end); + curr.bufname = ctx.prev().buffername; + curr.base = Number(ctx.prev().end); } return curr.resolve(ctx); } @@ -182,8 +182,8 @@ std::optional AddressPromise::get_range(BEd &ctx, std::vector(curr.base)) { - curr.bufname = ctx.prev.buffername; - curr.base = Number(ctx.prev.end); + curr.bufname = ctx.prev().buffername; + curr.base = Number(ctx.prev().end); prev_given = true; } else { prev_given = true; @@ -210,7 +210,7 @@ std::optional AddressPromise::get_range(BEd &ctx, std::vector(curr.base)) { - return ctx.prev; + return ctx.prev(); } if (prev_given) return buffer::Range(prev.resolve(ctx), curr.resolve(ctx));