Rename ed to BEd
This commit is contained in:
@@ -10,12 +10,6 @@ Vase is a avl piece tree like structure which handles loading, insertion, erasur
|
|||||||
<br/>
|
<br/>
|
||||||
done.
|
done.
|
||||||
|
|
||||||
#### Ed
|
|
||||||
|
|
||||||
Ed is an ed (the posix line editor) implementation using `Vase`.
|
|
||||||
<br/>
|
|
||||||
Mostly done.
|
|
||||||
|
|
||||||
#### `hl`
|
#### `hl`
|
||||||
|
|
||||||
`hl` is a stateful super fast syntax highlighter.
|
`hl` is a stateful super fast syntax highlighter.
|
||||||
@@ -38,10 +32,10 @@ It should support:
|
|||||||
<br/>
|
<br/>
|
||||||
Not done yet.
|
Not done yet.
|
||||||
|
|
||||||
#### BEd
|
### BEd
|
||||||
|
|
||||||
Better ed.<br/>
|
Better ed.<br/>
|
||||||
An ed implementation but with:
|
An ed implementation (mostly posix compliant) but with:
|
||||||
- Lsp support for autocomplete suggetions when in ed text mode.
|
- Lsp support for autocomplete suggetions when in ed text mode.
|
||||||
- Autocomplete for language snippets + other words found near the cursor etc.
|
- Autocomplete for language snippets + other words found near the cursor etc.
|
||||||
- text mode where arrow keys etc. work as expected.
|
- text mode where arrow keys etc. work as expected.
|
||||||
@@ -73,3 +67,10 @@ An ed implementation but with:
|
|||||||
- Nerdfonts & themable colorized outputs.
|
- Nerdfonts & themable colorized outputs.
|
||||||
- Better address marking with ranges.
|
- Better address marking with ranges.
|
||||||
- & A lot more cool stuff.
|
- & A lot more cool stuff.
|
||||||
|
|
||||||
|
#### Implementation status:
|
||||||
|
|
||||||
|
- Internal buffer:
|
||||||
|
- Super fast and memory efficient buffer implementation done.
|
||||||
|
- Loading from files/subshell commands done.
|
||||||
|
- Most of the posix ed commands except regex ones done.
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
#include "internal/vase/vase.h"
|
#include "internal/vase/vase.h"
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
|
||||||
namespace crib::commands::ed {
|
namespace crib::commands::bed {
|
||||||
struct ed_error : std::runtime_error {
|
struct bed_error : std::runtime_error {
|
||||||
ed_error(const char *msg) : std::runtime_error(msg) {}
|
bed_error(const char *msg) : std::runtime_error(msg) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Command {
|
struct Command {
|
||||||
@@ -58,7 +58,7 @@ struct Command {
|
|||||||
std::string argument;
|
std::string argument;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ed {
|
struct BEd {
|
||||||
crib::internal::vase::Vase vase;
|
crib::internal::vase::Vase vase;
|
||||||
uint64_t line = 0;
|
uint64_t line = 0;
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
@@ -73,7 +73,7 @@ struct Ed {
|
|||||||
std::filesystem::path save_path = "";
|
std::filesystem::path save_path = "";
|
||||||
std::string last_message = "";
|
std::string last_message = "";
|
||||||
|
|
||||||
Ed(std::string file_path, bool suppress_mode, std::string prompt_)
|
BEd(std::string file_path, bool suppress_mode, std::string prompt_)
|
||||||
: vase("/tmp"), suppress_mode(suppress_mode), prompt(prompt_) {
|
: vase("/tmp"), suppress_mode(suppress_mode), prompt(prompt_) {
|
||||||
if (prompt == "")
|
if (prompt == "")
|
||||||
prompt = "*";
|
prompt = "*";
|
||||||
@@ -96,4 +96,4 @@ struct Ed {
|
|||||||
std::string summary();
|
std::string summary();
|
||||||
void help();
|
void help();
|
||||||
void run(std::vector<std::string>);
|
void run(std::vector<std::string>);
|
||||||
} // namespace crib::commands::ed
|
} // namespace crib::commands::bed
|
||||||
+5
-5
@@ -1,12 +1,12 @@
|
|||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
#include "commands/ed/ed.h"
|
#include "commands/bed/bed.h"
|
||||||
|
|
||||||
namespace crib::cli {
|
namespace crib::cli {
|
||||||
static const std::unordered_map<std::string, Command> commands = {
|
static const std::unordered_map<std::string, Command> commands = {
|
||||||
{"ed",
|
{"bed",
|
||||||
{crib::commands::ed::run,
|
{crib::commands::bed::run,
|
||||||
crib::commands::ed::summary,
|
crib::commands::bed::summary,
|
||||||
crib::commands::ed::help}},
|
crib::commands::bed::help}},
|
||||||
};
|
};
|
||||||
|
|
||||||
bool use_color() {
|
bool use_color() {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#include "commands/ed/ed.h"
|
#include "commands/bed/bed.h"
|
||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
|
|
||||||
namespace crib::commands::ed {
|
namespace crib::commands::bed {
|
||||||
std::string summary() {
|
std::string summary() {
|
||||||
return "A POSIX-compliant line editor.";
|
return "Better Ed, a modern take on a posix compliant line editor.";
|
||||||
}
|
}
|
||||||
|
|
||||||
void help() {}
|
void help() {}
|
||||||
@@ -26,15 +26,15 @@ void run(std::vector<std::string> args) {
|
|||||||
file = args[i];
|
file = args[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ed ed(file, suppress, prompt);
|
BEd bed(file, suppress, prompt);
|
||||||
std::string command;
|
std::string command;
|
||||||
while (true) {
|
while (true) {
|
||||||
std::string cmd;
|
std::string cmd;
|
||||||
if (ed.prompt_mode)
|
if (bed.prompt_mode)
|
||||||
std::cout << ed.prompt;
|
std::cout << bed.prompt;
|
||||||
bool eof = !std::getline(std::cin, cmd);
|
bool eof = !std::getline(std::cin, cmd);
|
||||||
if (!ed.handle(cmd, eof))
|
if (!bed.handle(cmd, eof))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace crib::commands::ed
|
} // namespace crib::commands::bed
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "commands/ed/ed.h"
|
#include "commands/bed/bed.h"
|
||||||
|
|
||||||
namespace crib::commands::ed {
|
namespace crib::commands::bed {
|
||||||
bool Ed::handle(std::string cmd, bool eof) {
|
bool BEd::handle(std::string cmd, bool eof) {
|
||||||
using namespace crib::internal::vase;
|
using namespace crib::internal::vase;
|
||||||
try {
|
try {
|
||||||
if (line > vase.lines())
|
if (line > vase.lines())
|
||||||
@@ -15,7 +15,7 @@ bool Ed::handle(std::string cmd, bool eof) {
|
|||||||
case Command::Type::Quit:
|
case Command::Type::Quit:
|
||||||
if (modified && !was_quitting) {
|
if (modified && !was_quitting) {
|
||||||
quitting = true;
|
quitting = true;
|
||||||
throw ed_error("Buffer modified.");
|
throw bed_error("Buffer modified.");
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -31,15 +31,15 @@ bool Ed::handle(std::string cmd, bool eof) {
|
|||||||
line++;
|
line++;
|
||||||
}
|
}
|
||||||
if (line == 0)
|
if (line == 0)
|
||||||
throw ed_error("Line 0 is invalid.");
|
throw bed_error("Line 0 is invalid.");
|
||||||
if (line > vase.lines())
|
if (line > vase.lines())
|
||||||
throw ed_error("Line position too high.");
|
throw bed_error("Line position too high.");
|
||||||
Iterator it = vase.iterate(line - 1, Direction::Forward);
|
Iterator it = vase.iterate(line - 1, Direction::Forward);
|
||||||
it.next();
|
it.next();
|
||||||
std::cout << it.line << std::endl;
|
std::cout << it.line << std::endl;
|
||||||
} break;
|
} break;
|
||||||
case Command::Type::Invalid:
|
case Command::Type::Invalid:
|
||||||
throw ed_error("Invalid command.");
|
throw bed_error("Invalid command.");
|
||||||
case Command::Type::HelpToggle:
|
case Command::Type::HelpToggle:
|
||||||
help_mode = !help_mode;
|
help_mode = !help_mode;
|
||||||
if (help_mode && last_message != "")
|
if (help_mode && last_message != "")
|
||||||
@@ -62,9 +62,9 @@ bool Ed::handle(std::string cmd, bool eof) {
|
|||||||
resolve_address(command.end, &line_end);
|
resolve_address(command.end, &line_end);
|
||||||
}
|
}
|
||||||
if (line_start == 0)
|
if (line_start == 0)
|
||||||
throw ed_error("Line 0 is invalid.");
|
throw bed_error("Line 0 is invalid.");
|
||||||
if (line_end < line_start)
|
if (line_end < line_start)
|
||||||
throw ed_error("Invalid address range.");
|
throw bed_error("Invalid address range.");
|
||||||
Iterator it = vase.iterate(line_start - 1, Direction::Forward);
|
Iterator it = vase.iterate(line_start - 1, Direction::Forward);
|
||||||
while (it.next() && line_start++ <= line_end)
|
while (it.next() && line_start++ <= line_end)
|
||||||
std::cout << it.line << std::endl;
|
std::cout << it.line << std::endl;
|
||||||
@@ -80,9 +80,9 @@ bool Ed::handle(std::string cmd, bool eof) {
|
|||||||
resolve_address(command.end, &line_end);
|
resolve_address(command.end, &line_end);
|
||||||
}
|
}
|
||||||
if (line_start == 0)
|
if (line_start == 0)
|
||||||
throw ed_error("Line 0 is invalid.");
|
throw bed_error("Line 0 is invalid.");
|
||||||
if (line_end < line_start)
|
if (line_end < line_start)
|
||||||
throw ed_error("Invalid address range.");
|
throw bed_error("Invalid address range.");
|
||||||
Iterator it = vase.iterate(line_start - 1, Direction::Forward);
|
Iterator it = vase.iterate(line_start - 1, Direction::Forward);
|
||||||
while (it.next() && line_start++ <= line_end)
|
while (it.next() && line_start++ <= line_end)
|
||||||
std::cout << list_string(it.line) << std::endl;
|
std::cout << list_string(it.line) << std::endl;
|
||||||
@@ -98,9 +98,9 @@ bool Ed::handle(std::string cmd, bool eof) {
|
|||||||
resolve_address(command.end, &line_end);
|
resolve_address(command.end, &line_end);
|
||||||
}
|
}
|
||||||
if (line_start == 0)
|
if (line_start == 0)
|
||||||
throw ed_error("Line 0 is invalid.");
|
throw bed_error("Line 0 is invalid.");
|
||||||
if (line_end < line_start)
|
if (line_end < line_start)
|
||||||
throw ed_error("Invalid address range.");
|
throw bed_error("Invalid address range.");
|
||||||
Iterator it = vase.iterate(line_start - 1, Direction::Forward);
|
Iterator it = vase.iterate(line_start - 1, Direction::Forward);
|
||||||
while (it.next() && line_start <= line_end)
|
while (it.next() && line_start <= line_end)
|
||||||
std::cout << line_start++ << "\t" << it.line << std::endl;
|
std::cout << line_start++ << "\t" << it.line << std::endl;
|
||||||
@@ -171,7 +171,7 @@ bool Ed::handle(std::string cmd, bool eof) {
|
|||||||
resolve_address(command.end, &line_end);
|
resolve_address(command.end, &line_end);
|
||||||
}
|
}
|
||||||
if (line_end < line_start)
|
if (line_end < line_start)
|
||||||
throw ed_error("Invalid address range.");
|
throw bed_error("Invalid address range.");
|
||||||
std::string text;
|
std::string text;
|
||||||
std::string cline;
|
std::string cline;
|
||||||
uint64_t line_count = 0;
|
uint64_t line_count = 0;
|
||||||
@@ -203,7 +203,7 @@ bool Ed::handle(std::string cmd, bool eof) {
|
|||||||
resolve_address(command.end, &line_end);
|
resolve_address(command.end, &line_end);
|
||||||
}
|
}
|
||||||
if (line_end < line_start)
|
if (line_end < line_start)
|
||||||
throw ed_error("Invalid address range.");
|
throw bed_error("Invalid address range.");
|
||||||
vase.snapshot();
|
vase.snapshot();
|
||||||
vase.erase({{line_start - 1, 0}, {line_end, 0}});
|
vase.erase({{line_start - 1, 0}, {line_end, 0}});
|
||||||
modified = true;
|
modified = true;
|
||||||
@@ -216,7 +216,7 @@ bool Ed::handle(std::string cmd, bool eof) {
|
|||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
path = save_path;
|
path = save_path;
|
||||||
if (path.empty())
|
if (path.empty())
|
||||||
throw ed_error("Need file to write to.");
|
throw bed_error("Need file to write to.");
|
||||||
}
|
}
|
||||||
uint64_t line_start = 1;
|
uint64_t line_start = 1;
|
||||||
uint64_t line_end = vase.lines();
|
uint64_t line_end = vase.lines();
|
||||||
@@ -229,36 +229,36 @@ bool Ed::handle(std::string cmd, bool eof) {
|
|||||||
resolve_address(command.end, &line_end);
|
resolve_address(command.end, &line_end);
|
||||||
}
|
}
|
||||||
if (vase.lines() && line_start == 0)
|
if (vase.lines() && line_start == 0)
|
||||||
throw ed_error("Line 0 is invalid.");
|
throw bed_error("Line 0 is invalid.");
|
||||||
if (line_end < line_start)
|
if (line_end < line_start)
|
||||||
throw ed_error("Invalid address range.");
|
throw bed_error("Invalid address range.");
|
||||||
uint64_t bytes = 0;
|
uint64_t bytes = 0;
|
||||||
if (path[0] == '!') {
|
if (path[0] == '!') {
|
||||||
FILE *pipe = popen(path.c_str() + 1, "w");
|
FILE *pipe = popen(path.c_str() + 1, "w");
|
||||||
if (!pipe)
|
if (!pipe)
|
||||||
throw ed_error("Error starting command.");
|
throw bed_error("Error starting command.");
|
||||||
Iterator it = vase.iterate(line_start - 1, Direction::Forward);
|
Iterator it = vase.iterate(line_start - 1, Direction::Forward);
|
||||||
while (it.next() && line_start++ <= line_end) {
|
while (it.next() && line_start++ <= line_end) {
|
||||||
it.line += '\n';
|
it.line += '\n';
|
||||||
bytes += it.line.size();
|
bytes += it.line.size();
|
||||||
if (fputs(it.line.c_str(), pipe) == EOF) {
|
if (fputs(it.line.c_str(), pipe) == EOF) {
|
||||||
pclose(pipe);
|
pclose(pipe);
|
||||||
throw ed_error("Error writing to command.");
|
throw bed_error("Error writing to command.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pclose(pipe) == -1)
|
if (pclose(pipe) == -1)
|
||||||
throw ed_error("Error closing command.");
|
throw bed_error("Error closing command.");
|
||||||
} else {
|
} else {
|
||||||
std::ofstream file(path, std::ios::out | std::ios::trunc);
|
std::ofstream file(path, std::ios::out | std::ios::trunc);
|
||||||
if (!file)
|
if (!file)
|
||||||
throw ed_error("Error writing to file.");
|
throw bed_error("Error writing to file.");
|
||||||
Iterator it = vase.iterate(line_start - 1, Direction::Forward);
|
Iterator it = vase.iterate(line_start - 1, Direction::Forward);
|
||||||
while (it.next() && line_start++ <= line_end) {
|
while (it.next() && line_start++ <= line_end) {
|
||||||
file << it.line << '\n';
|
file << it.line << '\n';
|
||||||
bytes += it.line.size() + 1;
|
bytes += it.line.size() + 1;
|
||||||
}
|
}
|
||||||
if (!file)
|
if (!file)
|
||||||
throw ed_error("Error writing to file.");
|
throw bed_error("Error writing to file.");
|
||||||
save_path = path;
|
save_path = path;
|
||||||
modified = false;
|
modified = false;
|
||||||
}
|
}
|
||||||
@@ -275,9 +275,9 @@ bool Ed::handle(std::string cmd, bool eof) {
|
|||||||
resolve_address(command.end, &line_end);
|
resolve_address(command.end, &line_end);
|
||||||
}
|
}
|
||||||
if (line_end < line_start)
|
if (line_end < line_start)
|
||||||
throw ed_error("Invalid address range.");
|
throw bed_error("Invalid address range.");
|
||||||
if (line_start == 0)
|
if (line_start == 0)
|
||||||
throw ed_error("Invalid line number given.");
|
throw bed_error("Invalid line number given.");
|
||||||
if (line_end == line_start)
|
if (line_end == line_start)
|
||||||
break;
|
break;
|
||||||
vase.snapshot();
|
vase.snapshot();
|
||||||
@@ -294,20 +294,20 @@ bool Ed::handle(std::string cmd, bool eof) {
|
|||||||
resolve_address(command.start, &mark_line);
|
resolve_address(command.start, &mark_line);
|
||||||
}
|
}
|
||||||
if (mark_line == 0)
|
if (mark_line == 0)
|
||||||
throw ed_error("Invalid line number given.");
|
throw bed_error("Invalid line number given.");
|
||||||
char mark = command.argument[0];
|
char mark = command.argument[0];
|
||||||
marks[mark - 'a'] = mark_line;
|
marks[mark - 'a'] = mark_line;
|
||||||
} break;
|
} break;
|
||||||
case Command::Type::Edit: {
|
case Command::Type::Edit: {
|
||||||
if (modified && !was_editing) {
|
if (modified && !was_editing) {
|
||||||
editing = true;
|
editing = true;
|
||||||
throw ed_error("Buffer modified.");
|
throw bed_error("Buffer modified.");
|
||||||
}
|
}
|
||||||
std::string path = command.argument;
|
std::string path = command.argument;
|
||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
path = save_path;
|
path = save_path;
|
||||||
if (path.empty())
|
if (path.empty())
|
||||||
throw ed_error("Need file to read from.");
|
throw bed_error("Need file to read from.");
|
||||||
}
|
}
|
||||||
if (path[0] == '!') {
|
if (path[0] == '!') {
|
||||||
path.erase(1);
|
path.erase(1);
|
||||||
@@ -329,7 +329,7 @@ bool Ed::handle(std::string cmd, bool eof) {
|
|||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
path = save_path;
|
path = save_path;
|
||||||
if (path.empty())
|
if (path.empty())
|
||||||
throw ed_error("Need file to read from.");
|
throw bed_error("Need file to read from.");
|
||||||
}
|
}
|
||||||
if (path[0] == '!') {
|
if (path[0] == '!') {
|
||||||
path.erase(0, 1);
|
path.erase(0, 1);
|
||||||
@@ -350,7 +350,7 @@ bool Ed::handle(std::string cmd, bool eof) {
|
|||||||
case Command::Type::Filename: {
|
case Command::Type::Filename: {
|
||||||
std::string path = command.argument;
|
std::string path = command.argument;
|
||||||
if (path.empty())
|
if (path.empty())
|
||||||
throw ed_error("No filename given.");
|
throw bed_error("No filename given.");
|
||||||
save_path = path;
|
save_path = path;
|
||||||
std::cout << save_path.string() << std::endl;
|
std::cout << save_path.string() << std::endl;
|
||||||
} break;
|
} break;
|
||||||
@@ -373,7 +373,7 @@ bool Ed::handle(std::string cmd, bool eof) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (ed_error &e) {
|
} catch (bed_error &e) {
|
||||||
last_message = e.what();
|
last_message = e.what();
|
||||||
std::cout << "?" << std::endl;
|
std::cout << "?" << std::endl;
|
||||||
if (help_mode)
|
if (help_mode)
|
||||||
@@ -381,4 +381,4 @@ bool Ed::handle(std::string cmd, bool eof) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} // namespace crib::commands::ed
|
} // namespace crib::commands::bed
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "commands/ed/ed.h"
|
#include "commands/bed/bed.h"
|
||||||
|
|
||||||
namespace crib::commands::ed {
|
namespace crib::commands::bed {
|
||||||
void Ed::append(std::string text, uint64_t line) {
|
void BEd::append(std::string text, uint64_t line) {
|
||||||
using namespace crib::internal::vase;
|
using namespace crib::internal::vase;
|
||||||
Point p = {line, 0};
|
Point p = {line, 0};
|
||||||
if (!vase.lines()) {
|
if (!vase.lines()) {
|
||||||
@@ -15,15 +15,15 @@ void Ed::append(std::string text, uint64_t line) {
|
|||||||
vase.insert(&p, text);
|
vase.insert(&p, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ed::remove(uint64_t start_line, uint64_t end_line) {
|
void BEd::remove(uint64_t start_line, uint64_t end_line) {
|
||||||
vase.erase({{start_line - 1, 0}, {end_line, 0}});
|
vase.erase({{start_line - 1, 0}, {end_line, 0}});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ed::join(uint64_t start_line, uint64_t end_line) {
|
void BEd::join(uint64_t start_line, uint64_t end_line) {
|
||||||
vase.regex_search_replace("\\n", {{start_line - 1, 0}, {end_line, 0}}, "", "");
|
vase.regex_search_replace("\\n", {{start_line - 1, 0}, {end_line, 0}}, "", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Ed::list_string(std::string_view s) {
|
std::string BEd::list_string(std::string_view s) {
|
||||||
uint32_t width = 80;
|
uint32_t width = 80;
|
||||||
winsize ws{};
|
winsize ws{};
|
||||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col != 0)
|
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col != 0)
|
||||||
@@ -80,4 +80,4 @@ std::string Ed::list_string(std::string_view s) {
|
|||||||
out += '$';
|
out += '$';
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
} // namespace crib::commands::ed
|
} // namespace crib::commands::bed
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "commands/ed/ed.h"
|
#include "commands/bed/bed.h"
|
||||||
|
|
||||||
namespace crib::commands::ed {
|
namespace crib::commands::bed {
|
||||||
void Ed::parse_address(std::string_view cmd, uint64_t &i, Command::Address &addr) {
|
void BEd::parse_address(std::string_view cmd, uint64_t &i, Command::Address &addr) {
|
||||||
auto skip_space = [&] {
|
auto skip_space = [&] {
|
||||||
while (i < cmd.size() && (cmd[i] == ' ' || cmd[i] == '\t'))
|
while (i < cmd.size() && (cmd[i] == ' ' || cmd[i] == '\t'))
|
||||||
++i;
|
++i;
|
||||||
@@ -26,7 +26,7 @@ void Ed::parse_address(std::string_view cmd, uint64_t &i, Command::Address &addr
|
|||||||
if (i < cmd.size() && 'a' <= cmd[i] && cmd[i] <= 'z')
|
if (i < cmd.size() && 'a' <= cmd[i] && cmd[i] <= 'z')
|
||||||
i++;
|
i++;
|
||||||
else
|
else
|
||||||
throw ed_error("Invalid mark.");
|
throw bed_error("Invalid mark.");
|
||||||
addr.mark = cmd[i];
|
addr.mark = cmd[i];
|
||||||
break;
|
break;
|
||||||
case '/': {
|
case '/': {
|
||||||
@@ -135,7 +135,7 @@ void Ed::parse_address(std::string_view cmd, uint64_t &i, Command::Address &addr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ed::resolve_address(Command::Address addr, uint64_t *out_line) {
|
void BEd::resolve_address(Command::Address addr, uint64_t *out_line) {
|
||||||
switch (addr.type) {
|
switch (addr.type) {
|
||||||
case Command::Address::Type::None:
|
case Command::Address::Type::None:
|
||||||
break;
|
break;
|
||||||
@@ -153,7 +153,7 @@ void Ed::resolve_address(Command::Address addr, uint64_t *out_line) {
|
|||||||
case Command::Address::Type::Mark:
|
case Command::Address::Type::Mark:
|
||||||
*out_line = marks[addr.mark - 'a'];
|
*out_line = marks[addr.mark - 'a'];
|
||||||
if (!*out_line)
|
if (!*out_line)
|
||||||
throw ed_error("Unset mark used.");
|
throw bed_error("Unset mark used.");
|
||||||
break;
|
break;
|
||||||
case Command::Address::Type::SearchForward:
|
case Command::Address::Type::SearchForward:
|
||||||
if (addr.regex == "")
|
if (addr.regex == "")
|
||||||
@@ -169,10 +169,10 @@ void Ed::resolve_address(Command::Address addr, uint64_t *out_line) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((int64_t)*out_line + addr.offset < 0)
|
if ((int64_t)*out_line + addr.offset < 0)
|
||||||
throw ed_error("Line position can't be negative.");
|
throw bed_error("Line position can't be negative.");
|
||||||
else
|
else
|
||||||
*out_line += addr.offset;
|
*out_line += addr.offset;
|
||||||
if (*out_line > vase.lines())
|
if (*out_line > vase.lines())
|
||||||
throw ed_error("Line position too high.");
|
throw bed_error("Line position too high.");
|
||||||
}
|
}
|
||||||
} // namespace crib::commands::ed
|
} // namespace crib::commands::bed
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "commands/ed/ed.h"
|
#include "commands/bed/bed.h"
|
||||||
|
|
||||||
namespace crib::commands::ed {
|
namespace crib::commands::bed {
|
||||||
Command Ed::parse(std::string cmd, bool eof) {
|
Command BEd::parse(std::string cmd, bool eof) {
|
||||||
Command command = {};
|
Command command = {};
|
||||||
if (eof)
|
if (eof)
|
||||||
return (command.type = Command::Type::Quit, command);
|
return (command.type = Command::Type::Quit, command);
|
||||||
@@ -107,7 +107,7 @@ Command Ed::parse(std::string cmd, bool eof) {
|
|||||||
if (cmd[i] == ' ' || cmd[i] == '\t')
|
if (cmd[i] == ' ' || cmd[i] == '\t')
|
||||||
skip_space();
|
skip_space();
|
||||||
else
|
else
|
||||||
throw ed_error("Invalid command.");
|
throw bed_error("Invalid command.");
|
||||||
command.argument = cmd.substr(i);
|
command.argument = cmd.substr(i);
|
||||||
return command;
|
return command;
|
||||||
case 'e':
|
case 'e':
|
||||||
@@ -118,7 +118,7 @@ Command Ed::parse(std::string cmd, bool eof) {
|
|||||||
if (cmd[i] == ' ' || cmd[i] == '\t')
|
if (cmd[i] == ' ' || cmd[i] == '\t')
|
||||||
skip_space();
|
skip_space();
|
||||||
else
|
else
|
||||||
throw ed_error("Invalid command.");
|
throw bed_error("Invalid command.");
|
||||||
command.argument = cmd.substr(i);
|
command.argument = cmd.substr(i);
|
||||||
return command;
|
return command;
|
||||||
case 'E':
|
case 'E':
|
||||||
@@ -129,7 +129,7 @@ Command Ed::parse(std::string cmd, bool eof) {
|
|||||||
if (cmd[i] == ' ' || cmd[i] == '\t')
|
if (cmd[i] == ' ' || cmd[i] == '\t')
|
||||||
skip_space();
|
skip_space();
|
||||||
else
|
else
|
||||||
throw ed_error("Invalid command.");
|
throw bed_error("Invalid command.");
|
||||||
command.argument = cmd.substr(i);
|
command.argument = cmd.substr(i);
|
||||||
return command;
|
return command;
|
||||||
case 'f':
|
case 'f':
|
||||||
@@ -140,18 +140,18 @@ Command Ed::parse(std::string cmd, bool eof) {
|
|||||||
if (cmd[i] == ' ' || cmd[i] == '\t')
|
if (cmd[i] == ' ' || cmd[i] == '\t')
|
||||||
skip_space();
|
skip_space();
|
||||||
else
|
else
|
||||||
throw ed_error("Invalid command.");
|
throw bed_error("Invalid command.");
|
||||||
command.argument = cmd.substr(i);
|
command.argument = cmd.substr(i);
|
||||||
return command;
|
return command;
|
||||||
case 'k':
|
case 'k':
|
||||||
command.type = Command::Type::Mark;
|
command.type = Command::Type::Mark;
|
||||||
i++;
|
i++;
|
||||||
if (i >= cmd.size())
|
if (i >= cmd.size())
|
||||||
throw ed_error("Invalid command.");
|
throw bed_error("Invalid command.");
|
||||||
if ('a' <= cmd[i] && cmd[i] <= 'z')
|
if ('a' <= cmd[i] && cmd[i] <= 'z')
|
||||||
command.argument = cmd[i];
|
command.argument = cmd[i];
|
||||||
else
|
else
|
||||||
throw ed_error("Invalid mark used.");
|
throw bed_error("Invalid mark used.");
|
||||||
break;
|
break;
|
||||||
case '#':
|
case '#':
|
||||||
command.type = Command::Type::Dump;
|
command.type = Command::Type::Dump;
|
||||||
@@ -163,8 +163,8 @@ Command Ed::parse(std::string cmd, bool eof) {
|
|||||||
command.suffix = cmd[i++];
|
command.suffix = cmd[i++];
|
||||||
skip_space();
|
skip_space();
|
||||||
if (i != cmd.size())
|
if (i != cmd.size())
|
||||||
throw ed_error("Invalid command.");
|
throw bed_error("Invalid command.");
|
||||||
}
|
}
|
||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
} // namespace crib::commands::ed
|
} // namespace crib::commands::bed
|
||||||
Reference in New Issue
Block a user