1 #pragma once
2 #include "dispatcher.hpp"
3 #include "mutex.hpp"
4 #include "process.hpp"
5 #include "source_base.hpp"
6 #include <boost/filesystem.hpp>
7 #include <boost/optional.hpp>
8 #include <functional>
9 #include <gtkmm.h>
10 #include <iostream>
11 #include <tuple>
12 
13 class Terminal : public Source::CommonView {
14   Terminal();
15 
16 public:
get()17   static Terminal &get() {
18     static Terminal instance;
19     return instance;
20   }
21 
22   int process(const std::string &command, const boost::filesystem::path &path = "", bool use_pipes = true);
23   int process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path = "", std::ostream *stderr_stream = nullptr);
24   /// The callback is run in the main thread.
25   std::shared_ptr<TinyProcessLib::Process> async_process(const std::string &command, const boost::filesystem::path &path = "", std::function<void(int exit_status)> callback = nullptr, bool quiet = false);
26   void kill_last_async_process(bool force = false);
27   void kill_async_processes(bool force = false);
28 
29   /// Must be called from main thread
30   void print(std::string message, bool bold = false);
31   /// Callable from any thread.
32   void async_print(std::string message, bool bold = false);
33 
34   void configure();
35 
36   void clear();
37 
38   std::function<void()> scroll_to_bottom;
39 
40   void paste();
41 
42 protected:
43   bool on_motion_notify_event(GdkEventMotion *motion_event) override;
44   bool on_button_press_event(GdkEventButton *button_event) override;
45   bool on_key_press_event(GdkEventKey *event) override;
46 
47 private:
48   Dispatcher dispatcher;
49   Glib::RefPtr<Gtk::TextTag> bold_tag;
50   Glib::RefPtr<Gtk::TextTag> link_tag;
51   Glib::RefPtr<Gtk::TextTag> invisible_tag;
52   Glib::RefPtr<Gtk::TextTag> red_tag, green_tag, yellow_tag, blue_tag, magenta_tag, cyan_tag, gray_tag;
53   Glib::RefPtr<Gdk::Cursor> link_mouse_cursor;
54   Glib::RefPtr<Gdk::Cursor> default_mouse_cursor;
55 
56   struct Link {
57     int start_pos, end_pos;
58     std::string path;
59     int line, line_index;
60   };
61   static boost::optional<Link> find_link(const std::string &line);
62 
63   Mutex processes_mutex;
64   std::vector<std::shared_ptr<TinyProcessLib::Process>> processes GUARDED_BY(processes_mutex);
65   Glib::ustring stdin_buffer;
66 };
67