Files
bed/src/internal/buffer/buffer.cc
T

162 lines
3.6 KiB
C++

#include "internal/buffer/buffer.h"
namespace bed::internal::buffer {
Buffer::Buffer() : vase("/tmp") {
line = vase.lines();
modified = false;
}
Buffer::Buffer(std::string command) : vase(command, "/tmp") {
line = vase.lines();
if (!line)
return;
prev_range.start = 1;
prev_range.end = line;
modified = false;
}
Buffer::Buffer(std::filesystem::path path) : vase(path, "/tmp") {
line = vase.lines();
if (!line)
return;
prev_range.start = 1;
prev_range.end = line;
save_path = path;
modified = false;
}
void Buffer::load(std::string command) {
vase::Vase new_vase = vase::Vase(command, "/tmp");
vase = std::move(new_vase);
line = vase.lines();
if (!line) {
prev_range.start = 0;
prev_range.end = 0;
} else {
prev_range.start = 1;
prev_range.end = line;
}
modified = false;
}
void Buffer::load(std::filesystem::path path) {
vase::Vase new_vase = vase::Vase(path, "/tmp");
vase = std::move(new_vase);
line = vase.lines();
if (!line) {
prev_range.start = 0;
prev_range.end = 0;
} else {
prev_range.start = 1;
prev_range.end = line;
}
save_path = path;
modified = false;
}
void Buffer::jump(uint64_t n_line) {
if (n_line > vase.lines())
throw ed_error("Line number too high.");
line = n_line;
prev_range.start = line;
prev_range.end = line;
}
void Buffer::append(std::string text, uint64_t line) {
using namespace bed::internal::vase;
Point p = {line, 0};
if (!vase.lines()) {
text.pop_back();
} else if (line == vase.lines()) {
p.row--;
p.col = UINT64_MAX;
text = "\n" + text;
text.pop_back();
}
prev_range.start = p.row + 1;
vase.insert(&p, text);
prev_range.end = p.row + 1;
modified = true;
}
void Buffer::remove(uint64_t start_line, uint64_t end_line) {
vase.erase({{start_line - 1, 0}, {end_line, 0}});
prev_range.start = start_line;
prev_range.end = start_line;
modified = true;
}
void Buffer::join(uint64_t start_line, uint64_t end_line) {
vase.regex_search_replace(R"(\n)", {{start_line - 1, 0}, {end_line, 0}}, "", "g");
prev_range.start = start_line;
prev_range.end = start_line;
modified = true;
}
void Buffer::print(uint64_t start_line, uint64_t end_line) {
vase::Iterator it = vase.iterate(start_line - 1, Direction::Forward);
while (it.next() && start_line++ <= end_line)
std::cout << it.line << std::endl;
prev_range.start = start_line;
prev_range.end = end_line;
}
std::string Buffer::list_string(std::string_view s) {
uint32_t width = 80;
winsize ws{};
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col != 0)
width = ws.ws_col;
std::string out;
out.reserve(s.size());
const uint32_t max_width = width > 1 ? width - 1 : 1;
uint32_t column = 0;
auto append = [&](std::string_view text) {
if (column + text.size() > max_width) {
out += "\\\n";
column = 0;
}
out += text;
column += text.size();
};
for (unsigned char c : s) {
switch (c) {
case '\\':
append("\\\\");
break;
case '$':
append("\\$");
break;
case '\a':
append("\\a");
break;
case '\b':
append("\\b");
break;
case '\f':
append("\\f");
break;
case '\r':
append("\\r");
break;
case '\t':
append("\\t");
break;
case '\v':
append("\\v");
break;
default:
if (!std::isprint(c)) {
char buf[5];
std::snprintf(buf, sizeof(buf), "\\%03o", c);
append(buf);
} else {
append(std::string_view((const char *)&c, 1));
}
break;
}
}
out += '$';
return out;
}
} // namespace bed::internal::buffer