Add macro recording/replay support
This commit is contained in:
parent
577734dae7
commit
b43fdc7eb6
|
@ -690,9 +690,35 @@ void InputHandler::handle_available_inputs()
|
|||
{
|
||||
Key key = m_context.ui().get_key();
|
||||
if (is_valid(key))
|
||||
{
|
||||
const bool was_recording = is_recording();
|
||||
|
||||
m_mode->on_key(key);
|
||||
|
||||
// do not record the key that made us enter or leave recording mode.
|
||||
if (was_recording and is_recording())
|
||||
m_recorded_keys += key_to_str(key);
|
||||
}
|
||||
m_mode_trash.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void InputHandler::start_recording(char reg)
|
||||
{
|
||||
assert(m_recording_reg == 0);
|
||||
m_recording_reg = reg;
|
||||
}
|
||||
|
||||
bool InputHandler::is_recording() const
|
||||
{
|
||||
return m_recording_reg != 0;
|
||||
}
|
||||
|
||||
void InputHandler::stop_recording()
|
||||
{
|
||||
assert(m_recording_reg != 0);
|
||||
RegisterManager::instance()[m_recording_reg] = memoryview<String>(m_recorded_keys);
|
||||
m_recording_reg = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -65,6 +65,10 @@ public:
|
|||
// user interface
|
||||
void handle_available_inputs();
|
||||
|
||||
void start_recording(char reg);
|
||||
bool is_recording() const;
|
||||
void stop_recording();
|
||||
|
||||
Context& context() { return m_context; }
|
||||
private:
|
||||
Context m_context;
|
||||
|
@ -74,6 +78,9 @@ private:
|
|||
|
||||
using Insertion = std::pair<InsertMode, std::vector<Key>>;
|
||||
Insertion m_last_insert = {InsertMode::Insert, {}};
|
||||
|
||||
char m_recording_reg = 0;
|
||||
String m_recorded_keys;
|
||||
};
|
||||
|
||||
struct prompt_aborted {};
|
||||
|
|
|
@ -23,7 +23,8 @@ static std::vector<KeyAndName> keynamemap = {
|
|||
{ "left", Key::Left },
|
||||
{ "right", Key::Right },
|
||||
{ "up", Key::Up },
|
||||
{ "down", Key::Down}
|
||||
{ "down", Key::Down},
|
||||
{ "backspace", Key::Backspace}
|
||||
};
|
||||
|
||||
KeyList parse_keys(const String& str)
|
||||
|
|
30
src/main.cc
30
src/main.cc
|
@ -405,6 +405,33 @@ void select_to_next_char(Context& context)
|
|||
});
|
||||
}
|
||||
|
||||
void start_or_end_macro_recording(Context& context)
|
||||
{
|
||||
if (context.input_handler().is_recording())
|
||||
context.input_handler().stop_recording();
|
||||
else
|
||||
context.input_handler().on_next_key([](const Key& key, Context& context) {
|
||||
if (key.modifiers == Key::Modifiers::None)
|
||||
context.input_handler().start_recording(key.key);
|
||||
});
|
||||
}
|
||||
|
||||
void replay_macro(Context& context)
|
||||
{
|
||||
int count = context.numeric_param();
|
||||
context.input_handler().on_next_key([count](const Key& key, Context& context) mutable {
|
||||
if (key.modifiers == Key::Modifiers::None)
|
||||
{
|
||||
memoryview<String> reg_val = RegisterManager::instance()[key.key].values(context);
|
||||
if (not reg_val.empty())
|
||||
{
|
||||
scoped_edition edition(context.editor());
|
||||
do { exec_keys(parse_keys(reg_val[0]), context); } while (--count > 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
enum class JumpDirection { Forward, Backward };
|
||||
template<JumpDirection direction>
|
||||
void jump(Context& context)
|
||||
|
@ -590,6 +617,9 @@ std::unordered_map<Key, std::function<void (Context& context)>> keymap =
|
|||
{ { Key::Modifiers::Control, 'o' }, jump<JumpDirection::Backward> },
|
||||
|
||||
{ { Key::Modifiers::Alt, 'r' }, do_rotate_selections },
|
||||
|
||||
{ { Key::Modifiers::None, 'q' }, start_or_end_macro_recording },
|
||||
{ { Key::Modifiers::None, '@' }, replay_macro },
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user