Add support for arrow keys in normal mode
use a Direction enum instead of a bool forward parameter
This commit is contained in:
parent
6484fead0c
commit
37807ba19b
|
@ -258,10 +258,10 @@ void pipe(Context& context)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<SelectMode mode, bool forward>
|
template<SelectMode mode, Direction direction>
|
||||||
void search(Context& context)
|
void search(Context& context)
|
||||||
{
|
{
|
||||||
const char* prompt = forward ? "search:" : "reverse search:";
|
const char* prompt = direction == Forward ? "search:" : "reverse search:";
|
||||||
DynamicSelectionList selections{context.buffer(), context.editor().selections()};
|
DynamicSelectionList selections{context.buffer(), context.editor().selections()};
|
||||||
context.input_handler().prompt(prompt, get_color("Prompt"), complete_nothing,
|
context.input_handler().prompt(prompt, get_color("Prompt"), complete_nothing,
|
||||||
[selections](const String& str, PromptEvent event, Context& context) {
|
[selections](const String& str, PromptEvent event, Context& context) {
|
||||||
|
@ -285,7 +285,7 @@ void search(Context& context)
|
||||||
else if (str.empty() or not context.options()["incsearch"].get<bool>())
|
else if (str.empty() or not context.options()["incsearch"].get<bool>())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
context.editor().select(std::bind(select_next_match<forward>, _1, _2, ex), mode);
|
context.editor().select(std::bind(select_next_match<direction>, _1, _2, ex), mode);
|
||||||
}
|
}
|
||||||
catch (boost::regex_error& err)
|
catch (boost::regex_error& err)
|
||||||
{
|
{
|
||||||
|
@ -305,7 +305,7 @@ void search(Context& context)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<SelectMode mode, bool forward>
|
template<SelectMode mode, Direction direction>
|
||||||
void search_next(Context& context)
|
void search_next(Context& context)
|
||||||
{
|
{
|
||||||
const String& str = RegisterManager::instance()['/'].values(context)[0];
|
const String& str = RegisterManager::instance()['/'].values(context)[0];
|
||||||
|
@ -318,7 +318,7 @@ void search_next(Context& context)
|
||||||
context.push_jump();
|
context.push_jump();
|
||||||
int count = context.numeric_param();
|
int count = context.numeric_param();
|
||||||
do {
|
do {
|
||||||
context.editor().select(std::bind(select_next_match<forward>, _1, _2, ex), mode);
|
context.editor().select(std::bind(select_next_match<direction>, _1, _2, ex), mode);
|
||||||
} while (--count > 0);
|
} while (--count > 0);
|
||||||
}
|
}
|
||||||
catch (boost::regex_error& err)
|
catch (boost::regex_error& err)
|
||||||
|
@ -684,11 +684,10 @@ void replay_macro(Context& context)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class JumpDirection { Forward, Backward };
|
template<Direction direction>
|
||||||
template<JumpDirection direction>
|
|
||||||
void jump(Context& context)
|
void jump(Context& context)
|
||||||
{
|
{
|
||||||
auto jump = (direction == JumpDirection::Forward) ?
|
auto jump = (direction == Forward) ?
|
||||||
context.jump_forward() : context.jump_backward();
|
context.jump_forward() : context.jump_backward();
|
||||||
|
|
||||||
Buffer& buffer = const_cast<Buffer&>(jump.buffer());
|
Buffer& buffer = const_cast<Buffer&>(jump.buffer());
|
||||||
|
@ -755,17 +754,24 @@ private:
|
||||||
template<SelectMode mode, typename T>
|
template<SelectMode mode, typename T>
|
||||||
constexpr Select<mode, T> select(T func) { return Select<mode, T>(func); }
|
constexpr Select<mode, T> select(T func) { return Select<mode, T>(func); }
|
||||||
|
|
||||||
|
template<typename Type, Direction direction, SelectMode mode = SelectMode::Replace>
|
||||||
|
void move(Context& context)
|
||||||
|
{
|
||||||
|
Type offset(std::max(context.numeric_param(),1));
|
||||||
|
context.editor().move_selections(direction == Backward ? -offset : offset, mode);
|
||||||
|
}
|
||||||
|
|
||||||
KeyMap keymap =
|
KeyMap keymap =
|
||||||
{
|
{
|
||||||
{ { Key::Modifiers::None, 'h' }, [](Context& context) { context.editor().move_selections(-CharCount(std::max(context.numeric_param(),1))); } },
|
{ { Key::Modifiers::None, 'h' }, move<CharCount, Backward> },
|
||||||
{ { Key::Modifiers::None, 'j' }, [](Context& context) { context.editor().move_selections( LineCount(std::max(context.numeric_param(),1))); } },
|
{ { Key::Modifiers::None, 'j' }, move<LineCount, Forward> },
|
||||||
{ { Key::Modifiers::None, 'k' }, [](Context& context) { context.editor().move_selections(-LineCount(std::max(context.numeric_param(),1))); } },
|
{ { Key::Modifiers::None, 'k' }, move<LineCount, Backward> },
|
||||||
{ { Key::Modifiers::None, 'l' }, [](Context& context) { context.editor().move_selections( CharCount(std::max(context.numeric_param(),1))); } },
|
{ { Key::Modifiers::None, 'l' }, move<CharCount, Forward> },
|
||||||
|
|
||||||
{ { Key::Modifiers::None, 'H' }, [](Context& context) { context.editor().move_selections(-CharCount(std::max(context.numeric_param(),1)), SelectMode::Extend); } },
|
{ { Key::Modifiers::None, 'H' }, move<CharCount, Backward, SelectMode::Extend> },
|
||||||
{ { Key::Modifiers::None, 'J' }, [](Context& context) { context.editor().move_selections( LineCount(std::max(context.numeric_param(),1)), SelectMode::Extend); } },
|
{ { Key::Modifiers::None, 'J' }, move<LineCount, Forward, SelectMode::Extend> },
|
||||||
{ { Key::Modifiers::None, 'K' }, [](Context& context) { context.editor().move_selections(-LineCount(std::max(context.numeric_param(),1)), SelectMode::Extend); } },
|
{ { Key::Modifiers::None, 'K' }, move<LineCount, Backward, SelectMode::Extend> },
|
||||||
{ { Key::Modifiers::None, 'L' }, [](Context& context) { context.editor().move_selections( CharCount(std::max(context.numeric_param(),1)), SelectMode::Extend); } },
|
{ { Key::Modifiers::None, 'L' }, move<CharCount, Forward, SelectMode::Extend> },
|
||||||
|
|
||||||
{ { Key::Modifiers::None, 't' }, select_to_next_char<SelectFlags::None> },
|
{ { Key::Modifiers::None, 't' }, select_to_next_char<SelectFlags::None> },
|
||||||
{ { Key::Modifiers::None, 'f' }, select_to_next_char<SelectFlags::Inclusive> },
|
{ { Key::Modifiers::None, 'f' }, select_to_next_char<SelectFlags::Inclusive> },
|
||||||
|
@ -840,13 +846,13 @@ KeyMap keymap =
|
||||||
{ { Key::Modifiers::None, 'm' }, select<SelectMode::Replace>(select_matching) },
|
{ { Key::Modifiers::None, 'm' }, select<SelectMode::Replace>(select_matching) },
|
||||||
{ { Key::Modifiers::None, 'M' }, select<SelectMode::Extend>(select_matching) },
|
{ { Key::Modifiers::None, 'M' }, select<SelectMode::Extend>(select_matching) },
|
||||||
|
|
||||||
{ { Key::Modifiers::None, '/' }, search<SelectMode::Replace, true> },
|
{ { Key::Modifiers::None, '/' }, search<SelectMode::Replace, Forward> },
|
||||||
{ { Key::Modifiers::None, '?' }, search<SelectMode::Extend, true> },
|
{ { Key::Modifiers::None, '?' }, search<SelectMode::Extend, Forward> },
|
||||||
{ { Key::Modifiers::Alt, '/' }, search<SelectMode::Replace, false> },
|
{ { Key::Modifiers::Alt, '/' }, search<SelectMode::Replace, Backward> },
|
||||||
{ { Key::Modifiers::Alt, '?' }, search<SelectMode::Extend, false> },
|
{ { Key::Modifiers::Alt, '?' }, search<SelectMode::Extend, Backward> },
|
||||||
{ { Key::Modifiers::None, 'n' }, search_next<SelectMode::Replace, true> },
|
{ { Key::Modifiers::None, 'n' }, search_next<SelectMode::Replace, Forward> },
|
||||||
{ { Key::Modifiers::Alt, 'n' }, search_next<SelectMode::ReplaceMain, true> },
|
{ { Key::Modifiers::Alt, 'n' }, search_next<SelectMode::ReplaceMain, Forward> },
|
||||||
{ { Key::Modifiers::None, 'N' }, search_next<SelectMode::Append, true> },
|
{ { Key::Modifiers::None, 'N' }, search_next<SelectMode::Append, Forward> },
|
||||||
{ { Key::Modifiers::None, '*' }, use_selection_as_search_pattern<true> },
|
{ { Key::Modifiers::None, '*' }, use_selection_as_search_pattern<true> },
|
||||||
{ { Key::Modifiers::Alt, '*' }, use_selection_as_search_pattern<false> },
|
{ { Key::Modifiers::Alt, '*' }, use_selection_as_search_pattern<false> },
|
||||||
|
|
||||||
|
@ -867,11 +873,8 @@ KeyMap keymap =
|
||||||
{ { Key::Modifiers::None, '<' }, deindent },
|
{ { Key::Modifiers::None, '<' }, deindent },
|
||||||
{ { Key::Modifiers::None, '>' }, indent },
|
{ { Key::Modifiers::None, '>' }, indent },
|
||||||
|
|
||||||
{ { Key::Modifiers::None, Key::PageUp }, scroll<Key::PageUp> },
|
{ { Key::Modifiers::Control, 'i' }, jump<Forward> },
|
||||||
{ { Key::Modifiers::None, Key::PageDown }, scroll<Key::PageDown> },
|
{ { Key::Modifiers::Control, 'o' }, jump<Backward> },
|
||||||
|
|
||||||
{ { Key::Modifiers::Control, 'i' }, jump<JumpDirection::Forward> },
|
|
||||||
{ { Key::Modifiers::Control, 'o' }, jump<JumpDirection::Backward> },
|
|
||||||
|
|
||||||
{ { Key::Modifiers::Alt, 'r' }, rotate_selections },
|
{ { Key::Modifiers::Alt, 'r' }, rotate_selections },
|
||||||
|
|
||||||
|
@ -880,6 +883,14 @@ KeyMap keymap =
|
||||||
|
|
||||||
{ { Key::Modifiers::None, '~' }, swap_case },
|
{ { Key::Modifiers::None, '~' }, swap_case },
|
||||||
{ { Key::Modifiers::None, '&' }, align },
|
{ { Key::Modifiers::None, '&' }, align },
|
||||||
|
|
||||||
|
{ Key::Left, move<CharCount, Backward> },
|
||||||
|
{ Key::Down, move<LineCount, Forward> },
|
||||||
|
{ Key::Up, move<LineCount, Backward> },
|
||||||
|
{ Key::Right, move<CharCount, Forward> },
|
||||||
|
|
||||||
|
{ Key::PageUp, scroll<Key::PageUp> },
|
||||||
|
{ Key::PageDown, scroll<Key::PageDown> },
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -551,11 +551,11 @@ static bool find_last_match(BufferIterator begin, const BufferIterator& end,
|
||||||
return not res.empty();
|
return not res.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool forward>
|
template<Direction direction>
|
||||||
bool find_match_in_buffer(const Buffer& buffer, const BufferIterator pos,
|
bool find_match_in_buffer(const Buffer& buffer, const BufferIterator pos,
|
||||||
MatchResults& matches, const Regex& ex)
|
MatchResults& matches, const Regex& ex)
|
||||||
{
|
{
|
||||||
if (forward)
|
if (direction == Forward)
|
||||||
return (boost::regex_search(pos, buffer.end(), matches, ex) or
|
return (boost::regex_search(pos, buffer.end(), matches, ex) or
|
||||||
boost::regex_search(buffer.begin(), pos, matches, ex));
|
boost::regex_search(buffer.begin(), pos, matches, ex));
|
||||||
else
|
else
|
||||||
|
@ -564,7 +564,7 @@ bool find_match_in_buffer(const Buffer& buffer, const BufferIterator pos,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<bool forward>
|
template<Direction direction>
|
||||||
Selection select_next_match(const Buffer& buffer, const Selection& selection, const Regex& regex)
|
Selection select_next_match(const Buffer& buffer, const Selection& selection, const Regex& regex)
|
||||||
{
|
{
|
||||||
// regex matching do not use Utf8Iterator as boost::regex handle utf8
|
// regex matching do not use Utf8Iterator as boost::regex handle utf8
|
||||||
|
@ -575,7 +575,7 @@ Selection select_next_match(const Buffer& buffer, const Selection& selection, co
|
||||||
|
|
||||||
MatchResults matches;
|
MatchResults matches;
|
||||||
|
|
||||||
if (find_match_in_buffer<forward>(buffer, utf8::next(begin), matches, regex))
|
if (find_match_in_buffer<direction>(buffer, utf8::next(begin), matches, regex))
|
||||||
{
|
{
|
||||||
begin = matches[0].first;
|
begin = matches[0].first;
|
||||||
end = matches[0].second;
|
end = matches[0].second;
|
||||||
|
@ -589,12 +589,12 @@ Selection select_next_match(const Buffer& buffer, const Selection& selection, co
|
||||||
++end;
|
++end;
|
||||||
|
|
||||||
end = utf8::previous(end);
|
end = utf8::previous(end);
|
||||||
if (not forward)
|
if (direction == Backward)
|
||||||
std::swap(begin, end);
|
std::swap(begin, end);
|
||||||
return Selection{begin.coord(), end.coord(), std::move(captures)};
|
return Selection{begin.coord(), end.coord(), std::move(captures)};
|
||||||
}
|
}
|
||||||
template Selection select_next_match<true>(const Buffer&, const Selection&, const Regex&);
|
template Selection select_next_match<Forward>(const Buffer&, const Selection&, const Regex&);
|
||||||
template Selection select_next_match<false>(const Buffer&, const Selection&, const Regex&);
|
template Selection select_next_match<Backward>(const Buffer&, const Selection&, const Regex&);
|
||||||
|
|
||||||
SelectionList select_all_matches(const Buffer& buffer, const Selection& selection, const Regex& regex)
|
SelectionList select_all_matches(const Buffer& buffer, const Selection& selection, const Regex& regex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,7 +52,9 @@ Selection select_whole_lines(const Buffer& buffer, const Selection& selection);
|
||||||
Selection select_whole_buffer(const Buffer& buffer, const Selection& selection);
|
Selection select_whole_buffer(const Buffer& buffer, const Selection& selection);
|
||||||
Selection trim_partial_lines(const Buffer& buffer, const Selection& selection);
|
Selection trim_partial_lines(const Buffer& buffer, const Selection& selection);
|
||||||
|
|
||||||
template<bool forward>
|
enum Direction { Forward, Backward };
|
||||||
|
|
||||||
|
template<Direction direction>
|
||||||
Selection select_next_match(const Buffer& buffer, const Selection& selection,
|
Selection select_next_match(const Buffer& buffer, const Selection& selection,
|
||||||
const Regex& regex);
|
const Regex& regex);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user