mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-25 00:57:25 +08:00
Implement jump-to-matching-bracket motion and bind % (percent) in vi mode
Part of #1842
This commit is contained in:
parent
c966c19c56
commit
f8ebe346a9
|
@ -181,6 +181,7 @@ New or improved bindings
|
|||
- When the cursor is at the start of a line, escaping from insert mode no longer moves the cursor to the previous line.
|
||||
- Added bindings for clipboard interaction, like :kbd:`",+,p` and :kbd:`",+,y,y`.
|
||||
- Deleting in visual mode now moves the cursor back, matching vi (:issue:`10394`).
|
||||
- Support :kbd:`%` motion.
|
||||
|
||||
Completions
|
||||
^^^^^^^^^^^
|
||||
|
|
|
@ -258,6 +258,11 @@ The following special input functions are available:
|
|||
``repeat-jump`` and ``repeat-jump-reverse``
|
||||
redo the last jump in the same/opposite direction
|
||||
|
||||
``jump-to-matching-bracket``
|
||||
jump to matching bracket if the character under the cursor is bracket;
|
||||
otherwise, jump to the next occurence of *any right* bracket after the cursor.
|
||||
The following brackets are considered: ``([{}])``
|
||||
|
||||
``kill-bigword``
|
||||
move the next whitespace-delimited word to the killring
|
||||
|
||||
|
|
|
@ -238,6 +238,7 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish'
|
|||
bind -s --preset y,i backward-jump-till and repeat-jump-reverse and begin-selection repeat-jump kill-selection yank end-selection
|
||||
bind -s --preset y,a backward-jump and repeat-jump-reverse and begin-selection repeat-jump kill-selection yank end-selection
|
||||
|
||||
bind -s --preset % jump-to-matching-bracket
|
||||
bind -s --preset f forward-jump
|
||||
bind -s --preset F backward-jump
|
||||
bind -s --preset t forward-jump-till
|
||||
|
@ -305,6 +306,7 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish'
|
|||
bind -s --preset -M visual E 'set fish_cursor_end_mode exclusive' forward-single-char forward-bigword backward-char 'set fish_cursor_end_mode inclusive'
|
||||
bind -s --preset -M visual o swap-selection-start-stop repaint-mode
|
||||
|
||||
bind -s --preset -M visual % jump-to-matching-bracket
|
||||
bind -s --preset -M visual f forward-jump
|
||||
bind -s --preset -M visual t forward-jump-till
|
||||
bind -s --preset -M visual F backward-jump
|
||||
|
|
|
@ -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-to-matching-bracket"), ReadlineCmd::JumpToMatchingBracket),
|
||||
make_md(L!("kill-bigword"), ReadlineCmd::KillBigword),
|
||||
make_md(L!("kill-inner-line"), ReadlineCmd::KillInnerLine),
|
||||
make_md(L!("kill-line"), ReadlineCmd::KillLine),
|
||||
|
|
|
@ -109,6 +109,7 @@ pub enum ReadlineCmd {
|
|||
BackwardJump,
|
||||
ForwardJumpTill,
|
||||
BackwardJumpTill,
|
||||
JumpToMatchingBracket,
|
||||
FuncAnd,
|
||||
FuncOr,
|
||||
ExpandAbbr,
|
||||
|
|
|
@ -1739,6 +1739,42 @@ impl ReaderData {
|
|||
}
|
||||
}
|
||||
|
||||
fn jump_to_matching_bracket(
|
||||
&mut self,
|
||||
precision: JumpPrecision,
|
||||
elt: EditableLineTag,
|
||||
jump_from: usize,
|
||||
l_bracket: char,
|
||||
r_bracket: char,
|
||||
) -> bool {
|
||||
let el = self.edit_line(elt);
|
||||
let mut tmp_r_pos: usize = 0;
|
||||
let mut brackets_stack = Vec::new();
|
||||
while tmp_r_pos < el.len() {
|
||||
if el.at(tmp_r_pos) == l_bracket {
|
||||
brackets_stack.push(tmp_r_pos);
|
||||
} else if el.at(tmp_r_pos) == r_bracket {
|
||||
match brackets_stack.pop() {
|
||||
Some(tmp_l_pos) if jump_from == tmp_l_pos => {
|
||||
return match precision {
|
||||
JumpPrecision::Till => self.update_buff_pos(elt, Some(tmp_r_pos - 1)),
|
||||
JumpPrecision::To => self.update_buff_pos(elt, Some(tmp_r_pos)),
|
||||
};
|
||||
}
|
||||
Some(tmp_l_pos) if jump_from == tmp_r_pos => {
|
||||
return match precision {
|
||||
JumpPrecision::Till => self.update_buff_pos(elt, Some(tmp_l_pos + 1)),
|
||||
JumpPrecision::To => self.update_buff_pos(elt, Some(tmp_l_pos)),
|
||||
};
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
tmp_r_pos += 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
fn jump_and_remember_last_jump(
|
||||
&mut self,
|
||||
direction: JumpDirection,
|
||||
|
@ -3113,6 +3149,41 @@ impl<'a> Reader<'a> {
|
|||
self.input_data.function_set_status(success);
|
||||
}
|
||||
}
|
||||
rl::JumpToMatchingBracket => {
|
||||
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 {
|
||||
// If we stand on non-bracket character, we prefer to jump forward
|
||||
self.jump(JumpDirection::Forward, precision, elt, r_brackets.to_vec())
|
||||
};
|
||||
self.input_data.function_set_status(success);
|
||||
}
|
||||
rl::RepeatJump => {
|
||||
let (elt, _el) = self.active_edit_line();
|
||||
let mut success = false;
|
||||
|
|
Loading…
Reference in New Issue
Block a user