162 lines
3.6 KiB
C++
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
|