mirror of
https://github.com/RGBCube/serenity
synced 2025-07-10 04:37:35 +00:00
Shell+LibLine: Move Shell::{load,save}_history() to Line::Editor
This allows us to easily re-use history loading and saving in other programs using Line::Editor, as well as implementing universally recognized HISTCONTROL.
This commit is contained in:
parent
af05671843
commit
b2e4fe1299
6 changed files with 36 additions and 31 deletions
|
@ -34,6 +34,7 @@
|
||||||
#include <LibCore/ConfigFile.h>
|
#include <LibCore/ConfigFile.h>
|
||||||
#include <LibCore/Event.h>
|
#include <LibCore/Event.h>
|
||||||
#include <LibCore/EventLoop.h>
|
#include <LibCore/EventLoop.h>
|
||||||
|
#include <LibCore/File.h>
|
||||||
#include <LibCore/Notifier.h>
|
#include <LibCore/Notifier.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
@ -212,6 +213,32 @@ void Editor::add_to_history(const String& line)
|
||||||
m_history.append(line);
|
m_history.append(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Editor::load_history(const String& path)
|
||||||
|
{
|
||||||
|
auto history_file = Core::File::construct(path);
|
||||||
|
if (!history_file->open(Core::IODevice::ReadOnly))
|
||||||
|
return false;
|
||||||
|
while (history_file->can_read_line()) {
|
||||||
|
auto b = history_file->read_line(1024);
|
||||||
|
// skip the newline and terminating bytes
|
||||||
|
add_to_history(String(reinterpret_cast<const char*>(b.data()), b.size() - 2));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Editor::save_history(const String& path)
|
||||||
|
{
|
||||||
|
auto file_or_error = Core::File::open(path, Core::IODevice::WriteOnly, 0600);
|
||||||
|
if (file_or_error.is_error())
|
||||||
|
return false;
|
||||||
|
auto& file = *file_or_error.value();
|
||||||
|
for (const auto& line : m_history) {
|
||||||
|
file.write(line);
|
||||||
|
file.write("\n");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Editor::clear_line()
|
void Editor::clear_line()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < m_cursor; ++i)
|
for (size_t i = 0; i < m_cursor; ++i)
|
||||||
|
|
|
@ -143,7 +143,9 @@ public:
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
void add_to_history(const String&);
|
void add_to_history(const String& line);
|
||||||
|
bool load_history(const String& path);
|
||||||
|
bool save_history(const String& path);
|
||||||
const Vector<String>& history() const { return m_history; }
|
const Vector<String>& history() const { return m_history; }
|
||||||
|
|
||||||
void register_key_input_callback(const KeyBinding&);
|
void register_key_input_callback(const KeyBinding&);
|
||||||
|
|
|
@ -267,7 +267,7 @@ int Shell::builtin_exit(int argc, const char** argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stop_all_jobs();
|
stop_all_jobs();
|
||||||
save_history();
|
m_editor->save_history(get_history_path());
|
||||||
if (m_is_interactive)
|
if (m_is_interactive)
|
||||||
printf("Good-bye!\n");
|
printf("Good-bye!\n");
|
||||||
exit(exit_code);
|
exit(exit_code);
|
||||||
|
|
|
@ -966,30 +966,6 @@ String Shell::get_history_path()
|
||||||
return builder.to_string();
|
return builder.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shell::load_history()
|
|
||||||
{
|
|
||||||
auto history_file = Core::File::construct(get_history_path());
|
|
||||||
if (!history_file->open(Core::IODevice::ReadOnly))
|
|
||||||
return;
|
|
||||||
while (history_file->can_read_line()) {
|
|
||||||
auto b = history_file->read_line(1024);
|
|
||||||
// skip the newline and terminating bytes
|
|
||||||
m_editor->add_to_history(String(reinterpret_cast<const char*>(b.data()), b.size() - 2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shell::save_history()
|
|
||||||
{
|
|
||||||
auto file_or_error = Core::File::open(get_history_path(), Core::IODevice::WriteOnly, 0600);
|
|
||||||
if (file_or_error.is_error())
|
|
||||||
return;
|
|
||||||
auto& file = *file_or_error.value();
|
|
||||||
for (const auto& line : m_editor->history()) {
|
|
||||||
file.write(line);
|
|
||||||
file.write("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String Shell::escape_token(const String& token)
|
String Shell::escape_token(const String& token)
|
||||||
{
|
{
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
|
@ -1559,7 +1535,7 @@ Shell::Shell(Line::Editor& editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
directory_stack.append(cwd);
|
directory_stack.append(cwd);
|
||||||
load_history();
|
m_editor->load_history(get_history_path());
|
||||||
cache_path();
|
cache_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1569,7 +1545,7 @@ Shell::~Shell()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
stop_all_jobs();
|
stop_all_jobs();
|
||||||
save_history();
|
m_editor->save_history(get_history_path());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shell::stop_all_jobs()
|
void Shell::stop_all_jobs()
|
||||||
|
|
|
@ -109,6 +109,8 @@ public:
|
||||||
|
|
||||||
String format(const StringView&, ssize_t& cursor) const;
|
String format(const StringView&, ssize_t& cursor) const;
|
||||||
|
|
||||||
|
RefPtr<Line::Editor> editor() const { return m_editor; }
|
||||||
|
|
||||||
struct LocalFrame {
|
struct LocalFrame {
|
||||||
HashMap<String, RefPtr<AST::Value>> local_variables;
|
HashMap<String, RefPtr<AST::Value>> local_variables;
|
||||||
};
|
};
|
||||||
|
@ -154,8 +156,6 @@ public:
|
||||||
void kill_job(const Job*, int sig);
|
void kill_job(const Job*, int sig);
|
||||||
|
|
||||||
String get_history_path();
|
String get_history_path();
|
||||||
void load_history();
|
|
||||||
void save_history();
|
|
||||||
void print_path(const String& path);
|
void print_path(const String& path);
|
||||||
|
|
||||||
bool read_single_line();
|
bool read_single_line();
|
||||||
|
|
|
@ -57,7 +57,7 @@ int main(int argc, char** argv)
|
||||||
for (auto& it : s_shell->jobs)
|
for (auto& it : s_shell->jobs)
|
||||||
s_shell->kill_job(it.value.ptr(), SIGHUP);
|
s_shell->kill_job(it.value.ptr(), SIGHUP);
|
||||||
|
|
||||||
s_shell->save_history();
|
s_shell->editor()->save_history(s_shell->get_history_path());
|
||||||
});
|
});
|
||||||
|
|
||||||
editor = Line::Editor::construct();
|
editor = Line::Editor::construct();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue