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)
This commit is contained in:
2026-09-11 22:35:06 +01:00
parent a8d51dc0b6
commit 3346bc9f83
11 changed files with 31 additions and 15 deletions
+4
View File
@@ -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.)
+1
View File
@@ -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(
+1
View File
@@ -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;
+1
View File
@@ -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;
+1
View File
@@ -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;
}
+17 -10
View File
@@ -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;
}
+2
View File
@@ -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;
+1 -1
View File
@@ -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) {
+2 -2
View File
@@ -416,8 +416,7 @@ void Function::register_posix(BEd &ctx) {
auto addr = std::get<buffer::Range>(addr_);
auto arg = std::get<buffer::Line>(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));
}
+1
View File
@@ -35,6 +35,7 @@ inline uint8_t utf8_codepoint_width(unsigned char c) {
}
bool handle_escapes(RubyParser &p, std::vector<io::Token> *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});
-2
View File
@@ -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);