From 3346bc9f83dc9b64cd874ad2c92cbece7ecf4d63 Mon Sep 17 00:00:00 2001 From: Syed Daanish Date: Fri, 11 Sep 2026 22:35:06 +0100 Subject: [PATCH] Fix a few bugs. - Moving lines after themselves didnt work. - moving empty lines deleted them. - "w" didnt set state to unmodified in generic buffers. - in "hl" aligned the numbers (by digits) --- README.md | 4 ++++ include/internal/buffer/decl.h | 1 + include/internal/buffer/types/clip.h | 1 + include/internal/buffer/types/generic.h | 1 + include/internal/buffer/types/readonly.h | 1 + src/internal/buffer/generic.cc | 27 +++++++++++++++--------- src/internal/buffer/special/clip.cc | 2 ++ src/internal/functions/extended.cc | 2 +- src/internal/functions/posix.cc | 4 ++-- src/internal/syntax/ruby/parse.cc | 1 + src/internal/vase/vase.cc | 2 -- 11 files changed, 31 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 8bc487d..6ecdae5 100644 --- a/README.md +++ b/README.md @@ -58,3 +58,7 @@ It should support: Not done yet. +### TODO immediately: + +- Make "g" command work. +- properly handle escapes for %q ' etc in ruby parser (rn everything is escapable.) diff --git a/include/internal/buffer/decl.h b/include/internal/buffer/decl.h index 361c278..d3dfc30 100644 --- a/include/internal/buffer/decl.h +++ b/include/internal/buffer/decl.h @@ -34,6 +34,7 @@ struct Buffer { virtual uint64_t bytes() = 0; virtual void set_filename(std::filesystem::path path) = 0; virtual std::filesystem::path filename() = 0; + virtual void saved_hook() = 0; virtual void load(BEd &ctx, vase::Shard *text) = 0; virtual vase::Shard *copy(uint64_t start_line, uint64_t end_line) = 0; virtual void substitute( diff --git a/include/internal/buffer/types/clip.h b/include/internal/buffer/types/clip.h index cba4c3c..361f841 100644 --- a/include/internal/buffer/types/clip.h +++ b/include/internal/buffer/types/clip.h @@ -10,6 +10,7 @@ struct ClipBuffer : Buffer { void clip_write(vase::Shard *text); bool waste() override; + void saved_hook() override; uint64_t lines() override; uint64_t bytes() override; void load(BEd &ctx, vase::Shard *text) override; diff --git a/include/internal/buffer/types/generic.h b/include/internal/buffer/types/generic.h index 9ad0f49..4d43247 100644 --- a/include/internal/buffer/types/generic.h +++ b/include/internal/buffer/types/generic.h @@ -31,6 +31,7 @@ struct GenericBuffer : ShardBuffer { bool undo(BEd &ctx); bool redo(BEd &ctx); uint64_t prune(int); + void saved_hook() override; bool waste() override; void load(BEd &ctx, vase::Shard *text) override; void set_filename(std::filesystem::path path) override; diff --git a/include/internal/buffer/types/readonly.h b/include/internal/buffer/types/readonly.h index 26eb198..f9b52fd 100644 --- a/include/internal/buffer/types/readonly.h +++ b/include/internal/buffer/types/readonly.h @@ -12,6 +12,7 @@ struct ReadonlyBuffer : ShardBuffer { const syntax::ParserSnapshot &snapshot ) : ShardBuffer(std::move(name), root, snapshot, Kind::History) {} + void saved_hook() override {} bool waste() override { return useless; } diff --git a/src/internal/buffer/generic.cc b/src/internal/buffer/generic.cc index 37644e6..a0c035c 100644 --- a/src/internal/buffer/generic.cc +++ b/src/internal/buffer/generic.cc @@ -15,6 +15,8 @@ GenericBuffer::~GenericBuffer() { void GenericBuffer::list_history(BEd &ctx) { uint64_t current = base_version + undo_stack.size(); + uint64_t max_version = current + redo_stack.size(); + size_t width = std::to_string(max_version).size(); for (size_t i = 0; i < undo_stack.size(); ++i) { auto &item = undo_stack[i]; uint64_t version = base_version + i; @@ -22,8 +24,9 @@ void GenericBuffer::list_history(BEd &ctx) { std::tm tm = *std::localtime(&time); ctx.io.write_line( std::format( - " {} {:04}-{:02}-{:02} {:02}:{:02}:{:02} {}", + " {:>{}} {:04}-{:02}-{:02} {:02}:{:02}:{:02} {}", version, + width, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, @@ -39,8 +42,9 @@ void GenericBuffer::list_history(BEd &ctx) { std::tm tm = *std::localtime(&time); ctx.io.write_line( std::format( - "* {} {:04}-{:02}-{:02} {:02}:{:02}:{:02} {}", + "* {:>{}} {:04}-{:02}-{:02} {:02}:{:02}:{:02} {}", current, + width, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, @@ -58,8 +62,9 @@ void GenericBuffer::list_history(BEd &ctx) { std::tm tm = *std::localtime(&time); ctx.io.write_line( std::format( - " {} {:04}-{:02}-{:02} {:02}:{:02}:{:02} {}", + " {:>{}} {:04}-{:02}-{:02} {:02}:{:02}:{:02} {}", version, + width, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, @@ -207,6 +212,10 @@ bool GenericBuffer::waste() { && parse.lang == nullptr; } +void GenericBuffer::saved_hook() { + state = buffer::GenericBuffer::Unmodified; +} + void GenericBuffer::language(BEd &ctx, std::string name) { syntax::Language *lang = nullptr; if (name.size()) { @@ -253,17 +262,15 @@ std::filesystem::path GenericBuffer::filename() { }; void GenericBuffer::append(BEd &ctx, vase::Shard *text, uint64_t line) { - if (!text) - return; - snapshot(std::format("Insert {} lines after line {}", text->lines + 1, line)); + snapshot(std::format("Insert {} lines after line {}", (text ? text->lines + 1 : 1), line)); ctx.prev().buffername = name; ctx.prev().start = line + 1; - ctx.prev().end = line + text->lines + 1; - ctx.current() = {name, line + text->lines + 1}; + ctx.prev().end = line + (text ? text->lines + 1 : 1); + ctx.current() = {name, line + (text ? text->lines + 1 : 1)}; root = vase::insert(&ctx.append, root, text, line); - ctx.marks.insert(name, line, text->lines + 1); + ctx.marks.insert(name, line, (text ? text->lines + 1 : 1)); if (parse.lang) - syntax::insert(parse, root, line, text->lines + 1); + syntax::insert(parse, root, line, (text ? text->lines + 1 : 1)); state = Modified; } diff --git a/src/internal/buffer/special/clip.cc b/src/internal/buffer/special/clip.cc index 8fccc00..e52ed68 100644 --- a/src/internal/buffer/special/clip.cc +++ b/src/internal/buffer/special/clip.cc @@ -8,6 +8,8 @@ bool ClipBuffer::waste() { return false; } +void ClipBuffer::saved_hook() {} + uint64_t ClipBuffer::lines() { auto s = vase::Shard::from_command("xclip -selection clipboard -o", true); uint64_t lines = s ? s->lines + 1 : 0; diff --git a/src/internal/functions/extended.cc b/src/internal/functions/extended.cc index fdc07dd..4dab381 100644 --- a/src/internal/functions/extended.cc +++ b/src/internal/functions/extended.cc @@ -287,7 +287,7 @@ void Function::register_extented(BEd &ctx) { str[i - 1] = '\n'; continue; } - if (str[i] == '$' && i < str.size() && '1' <= str[i + 1] && str[i + 1] <= '4') { + if (str[i] == '$' && i + 1 < str.size() && '1' <= str[i + 1] && str[i + 1] <= '4') { char c = str[i + 1]; str.erase(i, 2); switch (c) { diff --git a/src/internal/functions/posix.cc b/src/internal/functions/posix.cc index d30fc9b..6fe964c 100644 --- a/src/internal/functions/posix.cc +++ b/src/internal/functions/posix.cc @@ -416,8 +416,7 @@ void Function::register_posix(BEd &ctx) { auto addr = std::get(addr_); auto arg = std::get(arg_); if (arg.buffername == addr.buffername - && addr.start <= arg.number - && addr.end < arg.number) + && arg.number >= addr.start && arg.number < addr.end) throw ed_error("Can't move lines within themselves."); auto text = ctx.buffer(addr.buffername).copy(addr.start, addr.end); ctx.mark(252, arg); @@ -757,6 +756,7 @@ void Function::register_posix(BEd &ctx) { vase::Shard::release(text); throw; } + buf.saved_hook(); if (!ctx.suppress_mode) ctx.io.write(std::format("{}\n", text ? text->length + 1 : 0)); } diff --git a/src/internal/syntax/ruby/parse.cc b/src/internal/syntax/ruby/parse.cc index b1f3cc9..134d026 100644 --- a/src/internal/syntax/ruby/parse.cc +++ b/src/internal/syntax/ruby/parse.cc @@ -35,6 +35,7 @@ inline uint8_t utf8_codepoint_width(unsigned char c) { } bool handle_escapes(RubyParser &p, std::vector *tokens, uint32_t &start, bool string = true) { + // TODO: properly handle escapes for %q ' etc. if (p.peek() == '\\') { if (string) tokens->push_back({start, p.i, io::Token::String}); diff --git a/src/internal/vase/vase.cc b/src/internal/vase/vase.cc index 45675e5..397e764 100644 --- a/src/internal/vase/vase.cc +++ b/src/internal/vase/vase.cc @@ -182,8 +182,6 @@ Shard *insert(AppendStorage *ap, Shard *root, Shard *text, uint64_t line) { Shard::retain(text); return text; } - if (!text) - return root; if (line > root->lines + 1) throw ed_error("line out of range"); Shard::retain(text);