mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-22 11:22:52 +08:00
Implement jump-till-matching-bracket input function
Part of #1842 It's like jump-to-matching-bracket, but jumps right before the bracket I will use it to mimic vi 'ab' and 'ib' text objects in the next commit Given complicated semantics of jump-till-matching-bracket, an alternative name could be 'jump-inside-matching-brackets'. But that would make names non-symmetrical. I'm not sure what is worse.
This commit is contained in:
parent
f8ebe346a9
commit
67e190876a
|
@ -263,6 +263,13 @@ The following special input functions are available:
|
|||
otherwise, jump to the next occurence of *any right* bracket after the cursor.
|
||||
The following brackets are considered: ``([{}])``
|
||||
|
||||
``jump-till-matching-bracket``
|
||||
the same as ``jump-to-matching-bracket`` but offset cursor to the right for left bracket, and offset cursor to the left for right bracket.
|
||||
The offset is applied for both the position we jump from and position we jump to.
|
||||
In other words, the cursor will continuously jump inside the brackets but won't reach them by 1 character.
|
||||
The input function is useful to emulate ``ib`` vi text object.
|
||||
The following brackets are considered: ``([{}])``
|
||||
|
||||
``kill-bigword``
|
||||
move the next whitespace-delimited word to the killring
|
||||
|
||||
|
|
|
@ -178,6 +178,7 @@ const INPUT_FUNCTION_METADATA: &[InputFunctionMetadata] = &[
|
|||
make_md(L!("history-token-search-forward"), ReadlineCmd::HistoryTokenSearchForward),
|
||||
make_md(L!("insert-line-over"), ReadlineCmd::InsertLineOver),
|
||||
make_md(L!("insert-line-under"), ReadlineCmd::InsertLineUnder),
|
||||
make_md(L!("jump-till-matching-bracket"), ReadlineCmd::JumpTillMatchingBracket),
|
||||
make_md(L!("jump-to-matching-bracket"), ReadlineCmd::JumpToMatchingBracket),
|
||||
make_md(L!("kill-bigword"), ReadlineCmd::KillBigword),
|
||||
make_md(L!("kill-inner-line"), ReadlineCmd::KillInnerLine),
|
||||
|
|
|
@ -110,6 +110,7 @@ pub enum ReadlineCmd {
|
|||
ForwardJumpTill,
|
||||
BackwardJumpTill,
|
||||
JumpToMatchingBracket,
|
||||
JumpTillMatchingBracket,
|
||||
FuncAnd,
|
||||
FuncOr,
|
||||
ExpandAbbr,
|
||||
|
|
|
@ -3149,38 +3149,59 @@ impl<'a> Reader<'a> {
|
|||
self.input_data.function_set_status(success);
|
||||
}
|
||||
}
|
||||
rl::JumpToMatchingBracket => {
|
||||
rl::JumpToMatchingBracket | rl::JumpTillMatchingBracket => {
|
||||
let (elt, _el) = self.active_edit_line();
|
||||
let el = self.edit_line(elt);
|
||||
let l_brackets = ['(', '[', '{'];
|
||||
let r_brackets = [')', ']', '}'];
|
||||
let jump_from_pos = el.position();
|
||||
let precision = JumpPrecision::To;
|
||||
let success = if l_brackets.contains(&el.at(jump_from_pos))
|
||||
|| r_brackets.contains(&el.at(jump_from_pos))
|
||||
{
|
||||
let l_bracket = match el.at(jump_from_pos) {
|
||||
'(' | ')' => '(',
|
||||
'[' | ']' => '[',
|
||||
'{' | '}' => '{',
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let r_bracket = match l_bracket {
|
||||
'(' => ')',
|
||||
'[' => ']',
|
||||
'{' => '}',
|
||||
_ => unreachable!(),
|
||||
};
|
||||
self.jump_to_matching_bracket(
|
||||
precision,
|
||||
elt,
|
||||
jump_from_pos,
|
||||
l_bracket,
|
||||
r_bracket,
|
||||
)
|
||||
} else {
|
||||
let cursor = el.position();
|
||||
let precision = match c {
|
||||
rl::JumpToMatchingBracket => JumpPrecision::To,
|
||||
rl::JumpTillMatchingBracket => JumpPrecision::Till,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let jump_from_pos = match c {
|
||||
_ if l_brackets.contains(&el.at(cursor))
|
||||
|| r_brackets.contains(&el.at(cursor)) =>
|
||||
{
|
||||
Some(cursor)
|
||||
}
|
||||
rl::JumpTillMatchingBracket
|
||||
if cursor > 0 && l_brackets.contains(&el.at(cursor - 1)) =>
|
||||
{
|
||||
Some(cursor - 1)
|
||||
}
|
||||
rl::JumpTillMatchingBracket
|
||||
if cursor < el.len() && r_brackets.contains(&el.at(cursor + 1)) =>
|
||||
{
|
||||
Some(cursor + 1)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
let success = match jump_from_pos {
|
||||
Some(jump_from_pos) => {
|
||||
let l_bracket = match el.at(jump_from_pos) {
|
||||
'(' | ')' => '(',
|
||||
'[' | ']' => '[',
|
||||
'{' | '}' => '{',
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let r_bracket = match l_bracket {
|
||||
'(' => ')',
|
||||
'[' => ']',
|
||||
'{' => '}',
|
||||
_ => unreachable!(),
|
||||
};
|
||||
self.jump_to_matching_bracket(
|
||||
precision,
|
||||
elt,
|
||||
jump_from_pos,
|
||||
l_bracket,
|
||||
r_bracket,
|
||||
)
|
||||
}
|
||||
// If we stand on non-bracket character, we prefer to jump forward
|
||||
self.jump(JumpDirection::Forward, precision, elt, r_brackets.to_vec())
|
||||
None => self.jump(JumpDirection::Forward, precision, elt, r_brackets.to_vec()),
|
||||
};
|
||||
self.input_data.function_set_status(success);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user