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:
@@ -58,3 +58,7 @@ It should support:
|
|||||||
|
|
||||||
Not done yet.
|
Not done yet.
|
||||||
|
|
||||||
|
### TODO immediately:
|
||||||
|
|
||||||
|
- Make "g" command work.
|
||||||
|
- properly handle escapes for %q ' etc in ruby parser (rn everything is escapable.)
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ struct Buffer {
|
|||||||
virtual uint64_t bytes() = 0;
|
virtual uint64_t bytes() = 0;
|
||||||
virtual void set_filename(std::filesystem::path path) = 0;
|
virtual void set_filename(std::filesystem::path path) = 0;
|
||||||
virtual std::filesystem::path filename() = 0;
|
virtual std::filesystem::path filename() = 0;
|
||||||
|
virtual void saved_hook() = 0;
|
||||||
virtual void load(BEd &ctx, vase::Shard *text) = 0;
|
virtual void load(BEd &ctx, vase::Shard *text) = 0;
|
||||||
virtual vase::Shard *copy(uint64_t start_line, uint64_t end_line) = 0;
|
virtual vase::Shard *copy(uint64_t start_line, uint64_t end_line) = 0;
|
||||||
virtual void substitute(
|
virtual void substitute(
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ struct ClipBuffer : Buffer {
|
|||||||
|
|
||||||
void clip_write(vase::Shard *text);
|
void clip_write(vase::Shard *text);
|
||||||
bool waste() override;
|
bool waste() override;
|
||||||
|
void saved_hook() override;
|
||||||
uint64_t lines() override;
|
uint64_t lines() override;
|
||||||
uint64_t bytes() override;
|
uint64_t bytes() override;
|
||||||
void load(BEd &ctx, vase::Shard *text) override;
|
void load(BEd &ctx, vase::Shard *text) override;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ struct GenericBuffer : ShardBuffer {
|
|||||||
bool undo(BEd &ctx);
|
bool undo(BEd &ctx);
|
||||||
bool redo(BEd &ctx);
|
bool redo(BEd &ctx);
|
||||||
uint64_t prune(int);
|
uint64_t prune(int);
|
||||||
|
void saved_hook() override;
|
||||||
bool waste() override;
|
bool waste() override;
|
||||||
void load(BEd &ctx, vase::Shard *text) override;
|
void load(BEd &ctx, vase::Shard *text) override;
|
||||||
void set_filename(std::filesystem::path path) override;
|
void set_filename(std::filesystem::path path) override;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ struct ReadonlyBuffer : ShardBuffer {
|
|||||||
const syntax::ParserSnapshot &snapshot
|
const syntax::ParserSnapshot &snapshot
|
||||||
) : ShardBuffer(std::move(name), root, snapshot, Kind::History) {}
|
) : ShardBuffer(std::move(name), root, snapshot, Kind::History) {}
|
||||||
|
|
||||||
|
void saved_hook() override {}
|
||||||
bool waste() override {
|
bool waste() override {
|
||||||
return useless;
|
return useless;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ GenericBuffer::~GenericBuffer() {
|
|||||||
|
|
||||||
void GenericBuffer::list_history(BEd &ctx) {
|
void GenericBuffer::list_history(BEd &ctx) {
|
||||||
uint64_t current = base_version + undo_stack.size();
|
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) {
|
for (size_t i = 0; i < undo_stack.size(); ++i) {
|
||||||
auto &item = undo_stack[i];
|
auto &item = undo_stack[i];
|
||||||
uint64_t version = base_version + i;
|
uint64_t version = base_version + i;
|
||||||
@@ -22,8 +24,9 @@ void GenericBuffer::list_history(BEd &ctx) {
|
|||||||
std::tm tm = *std::localtime(&time);
|
std::tm tm = *std::localtime(&time);
|
||||||
ctx.io.write_line(
|
ctx.io.write_line(
|
||||||
std::format(
|
std::format(
|
||||||
" {} {:04}-{:02}-{:02} {:02}:{:02}:{:02} {}",
|
" {:>{}} {:04}-{:02}-{:02} {:02}:{:02}:{:02} {}",
|
||||||
version,
|
version,
|
||||||
|
width,
|
||||||
tm.tm_year + 1900,
|
tm.tm_year + 1900,
|
||||||
tm.tm_mon + 1,
|
tm.tm_mon + 1,
|
||||||
tm.tm_mday,
|
tm.tm_mday,
|
||||||
@@ -39,8 +42,9 @@ void GenericBuffer::list_history(BEd &ctx) {
|
|||||||
std::tm tm = *std::localtime(&time);
|
std::tm tm = *std::localtime(&time);
|
||||||
ctx.io.write_line(
|
ctx.io.write_line(
|
||||||
std::format(
|
std::format(
|
||||||
"* {} {:04}-{:02}-{:02} {:02}:{:02}:{:02} {}",
|
"* {:>{}} {:04}-{:02}-{:02} {:02}:{:02}:{:02} {}",
|
||||||
current,
|
current,
|
||||||
|
width,
|
||||||
tm.tm_year + 1900,
|
tm.tm_year + 1900,
|
||||||
tm.tm_mon + 1,
|
tm.tm_mon + 1,
|
||||||
tm.tm_mday,
|
tm.tm_mday,
|
||||||
@@ -58,8 +62,9 @@ void GenericBuffer::list_history(BEd &ctx) {
|
|||||||
std::tm tm = *std::localtime(&time);
|
std::tm tm = *std::localtime(&time);
|
||||||
ctx.io.write_line(
|
ctx.io.write_line(
|
||||||
std::format(
|
std::format(
|
||||||
" {} {:04}-{:02}-{:02} {:02}:{:02}:{:02} {}",
|
" {:>{}} {:04}-{:02}-{:02} {:02}:{:02}:{:02} {}",
|
||||||
version,
|
version,
|
||||||
|
width,
|
||||||
tm.tm_year + 1900,
|
tm.tm_year + 1900,
|
||||||
tm.tm_mon + 1,
|
tm.tm_mon + 1,
|
||||||
tm.tm_mday,
|
tm.tm_mday,
|
||||||
@@ -207,6 +212,10 @@ bool GenericBuffer::waste() {
|
|||||||
&& parse.lang == nullptr;
|
&& parse.lang == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GenericBuffer::saved_hook() {
|
||||||
|
state = buffer::GenericBuffer::Unmodified;
|
||||||
|
}
|
||||||
|
|
||||||
void GenericBuffer::language(BEd &ctx, std::string name) {
|
void GenericBuffer::language(BEd &ctx, std::string name) {
|
||||||
syntax::Language *lang = nullptr;
|
syntax::Language *lang = nullptr;
|
||||||
if (name.size()) {
|
if (name.size()) {
|
||||||
@@ -253,17 +262,15 @@ std::filesystem::path GenericBuffer::filename() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void GenericBuffer::append(BEd &ctx, vase::Shard *text, uint64_t line) {
|
void GenericBuffer::append(BEd &ctx, vase::Shard *text, uint64_t line) {
|
||||||
if (!text)
|
snapshot(std::format("Insert {} lines after line {}", (text ? text->lines + 1 : 1), line));
|
||||||
return;
|
|
||||||
snapshot(std::format("Insert {} lines after line {}", text->lines + 1, line));
|
|
||||||
ctx.prev().buffername = name;
|
ctx.prev().buffername = name;
|
||||||
ctx.prev().start = line + 1;
|
ctx.prev().start = line + 1;
|
||||||
ctx.prev().end = line + text->lines + 1;
|
ctx.prev().end = line + (text ? text->lines + 1 : 1);
|
||||||
ctx.current() = {name, line + text->lines + 1};
|
ctx.current() = {name, line + (text ? text->lines + 1 : 1)};
|
||||||
root = vase::insert(&ctx.append, root, text, line);
|
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)
|
if (parse.lang)
|
||||||
syntax::insert(parse, root, line, text->lines + 1);
|
syntax::insert(parse, root, line, (text ? text->lines + 1 : 1));
|
||||||
state = Modified;
|
state = Modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ bool ClipBuffer::waste() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClipBuffer::saved_hook() {}
|
||||||
|
|
||||||
uint64_t ClipBuffer::lines() {
|
uint64_t ClipBuffer::lines() {
|
||||||
auto s = vase::Shard::from_command("xclip -selection clipboard -o", true);
|
auto s = vase::Shard::from_command("xclip -selection clipboard -o", true);
|
||||||
uint64_t lines = s ? s->lines + 1 : 0;
|
uint64_t lines = s ? s->lines + 1 : 0;
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ void Function::register_extented(BEd &ctx) {
|
|||||||
str[i - 1] = '\n';
|
str[i - 1] = '\n';
|
||||||
continue;
|
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];
|
char c = str[i + 1];
|
||||||
str.erase(i, 2);
|
str.erase(i, 2);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
|||||||
@@ -416,8 +416,7 @@ void Function::register_posix(BEd &ctx) {
|
|||||||
auto addr = std::get<buffer::Range>(addr_);
|
auto addr = std::get<buffer::Range>(addr_);
|
||||||
auto arg = std::get<buffer::Line>(arg_);
|
auto arg = std::get<buffer::Line>(arg_);
|
||||||
if (arg.buffername == addr.buffername
|
if (arg.buffername == addr.buffername
|
||||||
&& addr.start <= arg.number
|
&& arg.number >= addr.start && arg.number < addr.end)
|
||||||
&& addr.end < arg.number)
|
|
||||||
throw ed_error("Can't move lines within themselves.");
|
throw ed_error("Can't move lines within themselves.");
|
||||||
auto text = ctx.buffer(addr.buffername).copy(addr.start, addr.end);
|
auto text = ctx.buffer(addr.buffername).copy(addr.start, addr.end);
|
||||||
ctx.mark(252, arg);
|
ctx.mark(252, arg);
|
||||||
@@ -757,6 +756,7 @@ void Function::register_posix(BEd &ctx) {
|
|||||||
vase::Shard::release(text);
|
vase::Shard::release(text);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
buf.saved_hook();
|
||||||
if (!ctx.suppress_mode)
|
if (!ctx.suppress_mode)
|
||||||
ctx.io.write(std::format("{}\n", text ? text->length + 1 : 0));
|
ctx.io.write(std::format("{}\n", text ? text->length + 1 : 0));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
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 (p.peek() == '\\') {
|
||||||
if (string)
|
if (string)
|
||||||
tokens->push_back({start, p.i, io::Token::String});
|
tokens->push_back({start, p.i, io::Token::String});
|
||||||
|
|||||||
@@ -182,8 +182,6 @@ Shard *insert(AppendStorage *ap, Shard *root, Shard *text, uint64_t line) {
|
|||||||
Shard::retain(text);
|
Shard::retain(text);
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
if (!text)
|
|
||||||
return root;
|
|
||||||
if (line > root->lines + 1)
|
if (line > root->lines + 1)
|
||||||
throw ed_error("line out of range");
|
throw ed_error("line out of range");
|
||||||
Shard::retain(text);
|
Shard::retain(text);
|
||||||
|
|||||||
Reference in New Issue
Block a user