From a5272563567346ef1085d55c63934f41360d6784 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Tue, 11 May 2021 11:42:36 +0430 Subject: [PATCH] Shell: Add an option to autosave history every N ms ...and set it to 10 seconds by default. --- Base/etc/shellrc | 2 ++ Base/usr/share/man/man7/Shell-vars.md | 7 ++++++ Userland/Shell/Shell.cpp | 32 +++++++++++++++++++++++++++ Userland/Shell/Shell.h | 4 ++++ 4 files changed, 45 insertions(+) diff --git a/Base/etc/shellrc b/Base/etc/shellrc index 33b40ba1b9..2db638e0b5 100644 --- a/Base/etc/shellrc +++ b/Base/etc/shellrc @@ -38,3 +38,5 @@ if [ "$(id -u)" = "0" ] { } export PROMPT="\\X\\u@\\h:\\w\\a\\e[$prompt_color;1m\\h\\e[0m:\\e[34;1m\\w\\e[0m \\p " + +export HISTORY_AUTOSAVE_TIME_MS=10000 diff --git a/Base/usr/share/man/man7/Shell-vars.md b/Base/usr/share/man/man7/Shell-vars.md index 2666621ec6..abe51b7344 100644 --- a/Base/usr/share/man/man7/Shell-vars.md +++ b/Base/usr/share/man/man7/Shell-vars.md @@ -33,6 +33,13 @@ Note: This variable is respected by every program using `Line::Editor`, e.g. [`j The value of this variable is used as the Shell's history file path, both for reading history at startup and writing history on exit. Its default value is `~/.history`. +`HISTORY_AUTOSAVE_TIME_MS` (environment) + +Setting this variable to a value `t` other than zero (0) will make the shell save the history to the history file every `t` milliseconds. +If `t` is not a non-negative integer, zero will be assumed. +Note that multiple shell instances will not interfere with each other if they are to save to the same history file, instead, the entries will all be merged together chronologically. +The default value for this option is set in `/etc/shellrc`. + ## Visual 1. Prompting diff --git a/Userland/Shell/Shell.cpp b/Userland/Shell/Shell.cpp index 0dc3caae62..8737d8c3c7 100644 --- a/Userland/Shell/Shell.cpp +++ b/Userland/Shell/Shell.cpp @@ -1844,6 +1844,8 @@ Shell::Shell(Line::Editor& editor, bool attempt_interactive) return EDITOR_INTERNAL_FUNCTION(finish)(editor); }); + + start_timer(3000); } Shell::~Shell() @@ -2056,6 +2058,36 @@ Optional Shell::resolve_job_spec(const String& str) return {}; } +void Shell::timer_event(Core::TimerEvent& event) +{ + event.accept(); + + if (m_is_subshell) + return; + + StringView option = getenv("HISTORY_AUTOSAVE_TIME_MS"); + + auto time = option.to_uint(); + if (!time.has_value() || time.value() == 0) { + m_history_autosave_time.clear(); + stop_timer(); + start_timer(3000); + return; + } + + if (m_history_autosave_time != time) { + m_history_autosave_time = time.value(); + stop_timer(); + start_timer(m_history_autosave_time.value()); + } + + if (!m_history_autosave_time.has_value()) + return; + + if (m_editor) + m_editor->save_history(get_history_path()); +} + void FileDescriptionCollector::collect() { for (auto fd : m_fds) diff --git a/Userland/Shell/Shell.h b/Userland/Shell/Shell.h index 147d0f1b3f..61b48e3ac8 100644 --- a/Userland/Shell/Shell.h +++ b/Userland/Shell/Shell.h @@ -276,6 +276,8 @@ private: Shell(); virtual ~Shell() override; + void timer_event(Core::TimerEvent&) override; + // FIXME: Port to Core::Property void save_to(JsonObject&); void bring_cursor_to_beginning_of_a_line() const; @@ -347,6 +349,8 @@ private: bool m_default_constructed { false }; mutable bool m_last_continuation_state { false }; // false == not needed. + + Optional m_history_autosave_time; }; [[maybe_unused]] static constexpr bool is_word_character(char c)