mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 23:17:45 +00:00
Userland/JS: Add the 'save("file")' repl command
Calling save("file") in a repl saves all the typed lines so far into the specified file. It currently does not have great support for multilined functions since those get turned into one line.
This commit is contained in:
parent
56ca91b9f8
commit
fb67bc2f4f
1 changed files with 42 additions and 2 deletions
|
@ -44,6 +44,8 @@
|
|||
#include <LibLine/Editor.h>
|
||||
#include <stdio.h>
|
||||
|
||||
Vector<String> repl_statements;
|
||||
|
||||
class ReplObject : public JS::GlobalObject {
|
||||
public:
|
||||
ReplObject();
|
||||
|
@ -54,6 +56,7 @@ private:
|
|||
static JS::Value exit_interpreter(JS::Interpreter&);
|
||||
static JS::Value repl_help(JS::Interpreter&);
|
||||
static JS::Value load_file(JS::Interpreter&);
|
||||
static JS::Value save_to_file(JS::Interpreter&);
|
||||
};
|
||||
|
||||
bool dump_ast = false;
|
||||
|
@ -210,17 +213,54 @@ StringView strip_shebang(AK::ByteBuffer file_contents)
|
|||
return StringView((const char*)file_contents.data() + i, file_contents.size() - i);
|
||||
}
|
||||
|
||||
bool write_to_file(const StringView& path)
|
||||
{
|
||||
int fd = open_with_path_length(path.characters_without_null_termination(), path.length(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
for (size_t i = 0; i < repl_statements.size(); i++) {
|
||||
auto line = repl_statements[i];
|
||||
if (line.length() && i != repl_statements.size() - 1) {
|
||||
ssize_t nwritten = write(fd, line.characters(), line.length());
|
||||
if (nwritten < 0) {
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (i != repl_statements.size() - 1) {
|
||||
char ch = '\n';
|
||||
ssize_t nwritten = write(fd, &ch, 1);
|
||||
if (nwritten != 1) {
|
||||
perror("write");
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
ReplObject::ReplObject()
|
||||
{
|
||||
put_native_function("exit", exit_interpreter);
|
||||
put_native_function("help", repl_help);
|
||||
put_native_function("load", load_file);
|
||||
put_native_function("save", save_to_file);
|
||||
}
|
||||
|
||||
ReplObject::~ReplObject()
|
||||
{
|
||||
}
|
||||
|
||||
JS::Value ReplObject::save_to_file(JS::Interpreter& interpreter)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
return JS::Value(false);
|
||||
String save_path = interpreter.argument(0).to_string();
|
||||
StringView path = StringView(save_path.characters());
|
||||
if (write_to_file(path)) {
|
||||
return JS::Value(true);
|
||||
}
|
||||
return JS::Value(false);
|
||||
}
|
||||
JS::Value ReplObject::exit_interpreter(JS::Interpreter& interpreter)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
|
@ -274,7 +314,7 @@ void repl(JS::Interpreter& interpreter)
|
|||
String piece = read_next_piece();
|
||||
if (piece.is_empty())
|
||||
continue;
|
||||
|
||||
repl_statements.append(piece);
|
||||
auto program = JS::Parser(JS::Lexer(piece)).parse_program();
|
||||
if (dump_ast)
|
||||
program->dump(0);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue