1 /**
2  * @file
3  * @brief Crude macro-capability
4 **/
5 
6 #pragma once
7 
8 #include <deque>
9 #include <vector>
10 
11 #include "command-type.h"
12 #include "enum.h"
13 #include "KeymapContext.h"
14 
15 using std::vector;
16 
17 class key_recorder;
18 typedef deque<int> keyseq;
19 
20 class key_recorder
21 {
22 public:
23     bool                  paused;
24     keyseq                keys;
25 
26 public:
27     key_recorder();
28 
29     void add_key(int key, bool reverse = false);
30     void clear();
31 };
32 
33 class pause_all_key_recorders
34 {
35 public:
36     pause_all_key_recorders();
37     ~pause_all_key_recorders();
38 
39 private:
40     vector<bool> prev_pause_status;
41 };
42 
43 int getchm(KeymapContext context = KMC_DEFAULT);
44 
45 int get_ch();
46 
47 int getch_with_command_macros();  // keymaps and macros (ie for commands)
48 
49 void flush_input_buffer(int reason);
50 
51 void macro_quick_add();
52 void macro_menu();
53 void macro_init();
54 void macro_save();
55 
56 void macro_clear_buffers();
57 
58 void macro_userfn(const char *keys, const char *registryname);
59 
60 // Add macro-expanded keys to the end or start of the keyboard buffer.
61 void macro_sendkeys_end_add_expanded(int key);
62 void macro_sendkeys_end_add_cmd(command_type cmd);
63 
64 // [ds] Unless you know what you're doing, prefer macro_sendkeys_add_expanded
65 // to direct calls to macro_buf_add for pre-expanded key sequences.
66 //
67 // Crawl doesn't like holes in macro-expanded sequences in its main buffer.
68 void macro_buf_add(int key,
69                    bool reverse = false, bool expanded = true);
70 void macro_buf_add(const keyseq &actions,
71                    bool reverse = false, bool expanded = true);
72 int macro_buf_get();
73 
74 void macro_buf_add_cmd(command_type cmd, bool reverse = false);
75 void macro_buf_add_with_keymap(keyseq keys, KeymapContext mc);
76 
77 void process_command_on_record(command_type cmd);
78 
79 bool is_userfunction(int key);
80 bool is_synthetic_key(int key);
81 
82 string get_userfunction(int key);
83 
84 void add_key_recorder(key_recorder* recorder);
85 void remove_key_recorder(key_recorder* recorder);
86 
87 class key_recorder_raii
88 {
89 public:
key_recorder_raii(key_recorder * recorder)90     key_recorder_raii(key_recorder* recorder) : m_recorder(recorder)
91     {
92         add_key_recorder(m_recorder);
93     }
~key_recorder_raii()94     ~key_recorder_raii()
95     {
96         remove_key_recorder(m_recorder);
97     }
98 private:
99     key_recorder *m_recorder;
100 };
101 
102 bool is_processing_macro();
103 bool has_pending_input();
104 
105 int get_macro_buf_size();
106 
107 ///////////////////////////////////////////////////////////////
108 // Keybinding stuff
109 
110 void init_keybindings();
111 
112 command_type name_to_command(string name);
113 string  command_to_name(command_type cmd);
114 
115 int function_keycode_fixup(int keycode);
116 bool keycode_is_printable(int keycode);
117 string keycode_to_name(int keycode);
118 string keyseq_to_str(const keyseq &seq);
119 keyseq parse_keyseq(string s);
120 
121 command_type  key_to_command(int key, KeymapContext context);
122 int           command_to_key(command_type cmd);
123 
124 KeymapContext context_for_command(command_type cmd);
125 
126 void bind_command_to_key(command_type cmd, int key);
127 
128 string command_to_string(command_type cmd, bool tutorial = false);
129 void insert_commands(string &desc, const vector<command_type> &cmds,
130                      bool formatted = true);
131 
132 // Let rc files declare macros:
133 string read_rc_file_macro(const string& field);
134