1 /*
2  * RConsoleHistory.hpp
3  *
4  * Copyright (C) 2021 by RStudio, PBC
5  *
6  * Unless you have received this program directly from RStudio pursuant
7  * to the terms of a commercial license agreement with RStudio, then
8  * this program is licensed to you under the terms of version 3 of the
9  * GNU Affero General Public License. This program is distributed WITHOUT
10  * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12  * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13  *
14  */
15 
16 #ifndef R_SESSION_CONSOLE_HISTORY_HPP
17 #define R_SESSION_CONSOLE_HISTORY_HPP
18 
19 #include <string>
20 
21 #include <boost/utility.hpp>
22 #include <boost/circular_buffer.hpp>
23 
24 #include <core/BoostSignals.hpp>
25 #include <shared_core/json/Json.hpp>
26 
27 namespace rstudio {
28 namespace core {
29    class Error;
30    class FilePath;
31 }
32 }
33 
34 namespace rstudio {
35 namespace r {
36 namespace session {
37 
38 // singleton
39 class ConsoleHistory;
40 ConsoleHistory& consoleHistory();
41 
42 class ConsoleHistory : boost::noncopyable
43 {
44 public:
45    typedef boost::circular_buffer<std::string>::value_type value_type;
46    typedef boost::circular_buffer<std::string>::const_iterator const_iterator;
47    typedef RSTUDIO_BOOST_SIGNAL<void (const std::string&)> AddSignal;
48 
49 private:
50    ConsoleHistory();
51    friend ConsoleHistory& consoleHistory();
52    // COPYING: boost::noncopyable
53 
54 public:
55    void setCapacity(int capacity);
56 
57    void setCapacityFromRHistsize();
58 
capacity() const59    int capacity() const
60    {
61       return static_cast<int>(historyBuffer_.capacity());
62    }
63 
64    void setRemoveDuplicates(bool removeDuplicates);
65 
66    void add(const std::string& command);
67 
begin() const68    const_iterator begin() const { return historyBuffer_.begin(); }
end() const69    const_iterator end() const { return historyBuffer_.end(); }
70 
size() const71    int size() const
72    {
73       return static_cast<int>(historyBuffer_.size());
74    }
75 
76    void clear();
77 
78    void remove(const std::vector<int>& indexes);
79 
80    void subset(int beginIndex, // inclusive
81                int endIndex,   // exclusive,
82                std::vector<std::string>* pEntries) const;
83 
84    void asJson(core::json::Array* pHistoryArray) const;
85 
86    core::Error loadFromFile(const core::FilePath& filePath, bool verifyFile);
87    core::Error saveToFile(const core::FilePath& filePath) const;
88 
connectOnAdd(const AddSignal::slot_function_type & slot)89    RSTUDIO_BOOST_CONNECTION connectOnAdd(const AddSignal::slot_function_type& slot)
90    {
91       return onAdd_.connect(slot);
92    }
93 
94 private:
95    void safeRemove(int index);
96 
97 private:
98    bool removeDuplicates_;
99    boost::circular_buffer<std::string> historyBuffer_;
100    AddSignal onAdd_;
101 };
102 
103 } // namespace session
104 } // namespace r
105 } // namespace rstudio
106 
107 #endif // R_SESSION_CONSOLE_HISTORY_HPP
108 
109