mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:37:35 +00:00
LibLine: Unify history reading, prefer File over DeprecatedFile
This commit is contained in:
parent
64a2a63df6
commit
f93ee3142d
2 changed files with 37 additions and 28 deletions
|
@ -18,7 +18,6 @@
|
||||||
#include <AK/Utf32View.h>
|
#include <AK/Utf32View.h>
|
||||||
#include <AK/Utf8View.h>
|
#include <AK/Utf8View.h>
|
||||||
#include <LibCore/ConfigFile.h>
|
#include <LibCore/ConfigFile.h>
|
||||||
#include <LibCore/DeprecatedFile.h>
|
|
||||||
#include <LibCore/Event.h>
|
#include <LibCore/Event.h>
|
||||||
#include <LibCore/EventLoop.h>
|
#include <LibCore/EventLoop.h>
|
||||||
#include <LibCore/Notifier.h>
|
#include <LibCore/Notifier.h>
|
||||||
|
@ -249,26 +248,33 @@ void Editor::add_to_history(DeprecatedString const& line)
|
||||||
m_history_dirty = true;
|
m_history_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Editor::load_history(DeprecatedString const& path)
|
ErrorOr<Vector<Editor::HistoryEntry>> Editor::try_load_history(StringView path)
|
||||||
{
|
{
|
||||||
auto history_file_or_error = Core::File::open(path, Core::File::OpenMode::Read);
|
auto history_file = TRY(Core::File::open(path, Core::File::OpenMode::Read));
|
||||||
if (history_file_or_error.is_error())
|
auto data = TRY(history_file->read_until_eof());
|
||||||
return false;
|
auto hist = StringView { data };
|
||||||
auto data_or_error = history_file_or_error.value()->read_until_eof();
|
Vector<HistoryEntry> history;
|
||||||
if (data_or_error.is_error())
|
|
||||||
return false;
|
|
||||||
auto hist = StringView { data_or_error.value() };
|
|
||||||
for (auto& str : hist.split_view("\n\n"sv)) {
|
for (auto& str : hist.split_view("\n\n"sv)) {
|
||||||
auto it = str.find("::"sv).value_or(0);
|
auto it = str.find("::"sv).value_or(0);
|
||||||
auto time = str.substring_view(0, it).to_int<time_t>().value_or(0);
|
auto time = str.substring_view(0, it).to_int<time_t>().value_or(0);
|
||||||
auto string = str.substring_view(it == 0 ? it : it + 2);
|
auto string = str.substring_view(it == 0 ? it : it + 2);
|
||||||
m_history.append({ string, time });
|
history.append({ string, time });
|
||||||
}
|
}
|
||||||
return true;
|
return history;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename It0, typename It1, typename OutputT, typename MapperT, typename LessThan>
|
bool Editor::load_history(DeprecatedString const& path)
|
||||||
static void merge(It0&& begin0, It0 const& end0, It1&& begin1, It1 const& end1, OutputT& output, MapperT left_mapper, LessThan less_than)
|
{
|
||||||
|
auto history_or_error = try_load_history(path);
|
||||||
|
if (history_or_error.is_error())
|
||||||
|
return false;
|
||||||
|
auto maybe_error = m_history.try_extend(history_or_error.release_value());
|
||||||
|
auto okay = !maybe_error.is_error();
|
||||||
|
return okay;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename It0, typename It1, typename OutputT, typename LessThan>
|
||||||
|
static void merge(It0&& begin0, It0 const& end0, It1&& begin1, It1 const& end1, OutputT& output, LessThan less_than)
|
||||||
{
|
{
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (begin0 == end0 && begin1 == end1)
|
if (begin0 == end0 && begin1 == end1)
|
||||||
|
@ -282,7 +288,7 @@ static void merge(It0&& begin0, It0 const& end0, It1&& begin1, It1 const& end1,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto&& left = left_mapper(*begin0);
|
auto&& left = *begin0;
|
||||||
if (left.entry.is_whitespace()) {
|
if (left.entry.is_whitespace()) {
|
||||||
++begin0;
|
++begin0;
|
||||||
continue;
|
continue;
|
||||||
|
@ -311,30 +317,32 @@ static void merge(It0&& begin0, It0 const& end0, It1&& begin1, It1 const& end1,
|
||||||
|
|
||||||
bool Editor::save_history(DeprecatedString const& path)
|
bool Editor::save_history(DeprecatedString const& path)
|
||||||
{
|
{
|
||||||
|
// Note: Use a dummy entry to simplify merging.
|
||||||
Vector<HistoryEntry> final_history { { "", 0 } };
|
Vector<HistoryEntry> final_history { { "", 0 } };
|
||||||
{
|
{
|
||||||
auto file_or_error = Core::DeprecatedFile::open(path, Core::OpenMode::ReadWrite, 0600);
|
auto history_or_error = try_load_history(path);
|
||||||
if (file_or_error.is_error())
|
if (history_or_error.is_error())
|
||||||
return false;
|
return false;
|
||||||
auto file = file_or_error.release_value();
|
Vector<HistoryEntry> old_history = history_or_error.release_value();
|
||||||
merge(
|
merge(
|
||||||
file->line_begin(), file->line_end(), m_history.begin(), m_history.end(), final_history,
|
old_history.begin(), old_history.end(),
|
||||||
[](StringView str) {
|
m_history.begin(), m_history.end(),
|
||||||
auto it = str.find("::"sv).value_or(0);
|
final_history,
|
||||||
auto time = str.substring_view(0, it).to_int<time_t>().value_or(0);
|
|
||||||
auto string = str.substring_view(it == 0 ? it : it + 2);
|
|
||||||
return HistoryEntry { string, time };
|
|
||||||
},
|
|
||||||
[](HistoryEntry const& left, HistoryEntry const& right) { return left.timestamp < right.timestamp; });
|
[](HistoryEntry const& left, HistoryEntry const& right) { return left.timestamp < right.timestamp; });
|
||||||
}
|
}
|
||||||
|
|
||||||
auto file_or_error = Core::DeprecatedFile::open(path, Core::OpenMode::WriteOnly, 0600);
|
auto file_or_error = Core::File::open(path, Core::File::OpenMode::Write, 0600);
|
||||||
if (file_or_error.is_error())
|
if (file_or_error.is_error())
|
||||||
return false;
|
return false;
|
||||||
auto file = file_or_error.release_value();
|
auto file = file_or_error.release_value();
|
||||||
final_history.take_first();
|
// Skip the dummy entry:
|
||||||
for (auto const& entry : final_history)
|
for (auto iter = final_history.begin() + 1; iter != final_history.end(); ++iter) {
|
||||||
file->write(DeprecatedString::formatted("{}::{}\n\n", entry.timestamp, entry.entry));
|
auto const& entry = *iter;
|
||||||
|
auto buffer = DeprecatedString::formatted("{}::{}\n\n", entry.timestamp, entry.entry);
|
||||||
|
auto maybe_error = file->write_until_depleted(buffer.bytes());
|
||||||
|
if (maybe_error.is_error())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_history_dirty = false;
|
m_history_dirty = false;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -475,6 +475,7 @@ private:
|
||||||
size_t m_history_cursor { 0 };
|
size_t m_history_cursor { 0 };
|
||||||
size_t m_history_capacity { 1024 };
|
size_t m_history_capacity { 1024 };
|
||||||
bool m_history_dirty { false };
|
bool m_history_dirty { false };
|
||||||
|
static ErrorOr<Vector<HistoryEntry>> try_load_history(StringView path);
|
||||||
|
|
||||||
enum class InputState {
|
enum class InputState {
|
||||||
Free,
|
Free,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue