Index: lldb/include/lldb/Host/Editline.h =================================================================== --- lldb/include/lldb/Host/Editline.h +++ lldb/include/lldb/Host/Editline.h @@ -212,6 +212,8 @@ void PrintAsync(Stream *stream, const char *s, size_t len); + std::vector GetCommandHistory(); + private: /// Sets the lowest line number for multi-line editing sessions. A value of /// zero suppresses Index: lldb/include/lldb/Interpreter/CommandInterpreter.h =================================================================== --- lldb/include/lldb/Interpreter/CommandInterpreter.h +++ lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -487,6 +487,8 @@ const char *GetCommandPrefix(); // Properties + void AddCommandHistory(std::vector histories); + bool GetExpandRegexAliases() const; bool GetPromptOnQuit() const; Index: lldb/source/Core/IOHandler.cpp =================================================================== --- lldb/source/Core/IOHandler.cpp +++ lldb/source/Core/IOHandler.cpp @@ -266,8 +266,11 @@ m_color_prompts); m_editline_up->SetIsInputCompleteCallback(IsInputCompleteCallback, this); m_editline_up->SetAutoCompleteCallback(AutoCompleteCallback, this); - if (debugger.GetUseAutosuggestion() && debugger.GetUseColor()) + if (debugger.GetUseAutosuggestion() && debugger.GetUseColor()) { m_editline_up->SetSuggestionCallback(SuggestionCallback, this); + std::vector histories = m_editline_up->GetCommandHistory(); + this->GetDebugger().GetCommandInterpreter().AddCommandHistory(histories); + } // See if the delegate supports fixing indentation const char *indent_chars = delegate.IOHandlerGetFixIndentationCharacters(); if (indent_chars) { Index: lldb/source/Host/common/Editline.cpp =================================================================== --- lldb/source/Host/common/Editline.cpp +++ lldb/source/Host/common/Editline.cpp @@ -291,6 +291,28 @@ return false; } + std::vector GetAsStringList() { + this->Load(); + std::vector histories; + if (m_history) { + const char *path = GetHistoryFilePath(); + if (path) { + history_w(m_history, &m_event, H_GETSIZE); + int num = m_event.num; + for (int i = 0; i < num; ++i) { + history_w(m_history, &m_event, H_SET, i); + history_w(m_history, &m_event, H_CURR); + std::string string_history = + std::wstring_convert>().to_bytes( + m_event.str); + histories.push_back( + string_history.substr(0, string_history.length() - 1)); + } + } + } + return histories; + } + protected: HistoryW *m_history; // The history object HistEventW m_event; // The history event needed to contain all history events @@ -1599,3 +1621,7 @@ } #endif } + +std::vector Editline::GetCommandHistory() { + return m_history_sp->GetAsStringList(); +} \ No newline at end of file Index: lldb/source/Interpreter/CommandInterpreter.cpp =================================================================== --- lldb/source/Interpreter/CommandInterpreter.cpp +++ lldb/source/Interpreter/CommandInterpreter.cpp @@ -130,6 +130,12 @@ m_collection_sp->Initialize(g_interpreter_properties); } +void CommandInterpreter::AddCommandHistory(std::vector histories) { + for (const std::string &command : histories) { + m_command_history.AppendString(command); + } +} + bool CommandInterpreter::GetExpandRegexAliases() const { const uint32_t idx = ePropertyExpandRegexAliases; return m_collection_sp->GetPropertyAtIndexAsBoolean( Index: lldb/test/API/iohandler/autosuggestion/TestAutosuggestionFromPreviousSessions.py =================================================================== --- /dev/null +++ lldb/test/API/iohandler/autosuggestion/TestAutosuggestionFromPreviousSessions.py @@ -0,0 +1,38 @@ +""" +Tests autosuggestion from previous sessions using pexpect. +""" +import time +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test.lldbpexpect import PExpectTest + +def get_time(): + now_time = time.gmtime() + res = "" + for num in now_time: + res += str(num) + return res + + + +class TestCase(PExpectTest): + + mydir = TestBase.compute_mydir(__file__) + + # PExpect uses many timeouts internally and doesn't play well + # under ASAN on a loaded machine.. + @skipIfAsan + @skipIfEditlineSupportMissing + def test_autosuggestion_from_previous_sessions(self): + now_time = get_time() + self.launch(extra_args=["-o", "settings set show-autosuggestion true", "-o", "settings set use-color true"]) + + # Check if histories are saved after quit. + self.expect("expr " + now_time) + self.quit() + + self.launch(extra_args=["-o", "settings set show-autosuggestion true", "-o", "settings set use-color true"]) + + self.expect("session history", substrs=[now_time]) + self.quit() \ No newline at end of file