Make parse_util_token_extent return its output instead of mutating input.

This commit is contained in:
kerty 2025-01-21 16:16:47 +03:00 committed by Johannes Altmanninger
parent 4994000a27
commit b5c869d5e7
4 changed files with 30 additions and 61 deletions

View File

@ -216,7 +216,6 @@ pub fn commandline(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr])
let mut is_valid = false;
let mut showing_suggestion = false;
let mut range = 0..0;
let mut override_buffer = None;
const short_options: &wstr = L!(":abijpctfxorhI:CBELSsP");
@ -602,6 +601,7 @@ pub fn commandline(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr])
return Some(1);
}
let range;
if search_field_mode {
range = 0..current_buffer.len();
} else {
@ -616,7 +616,7 @@ pub fn commandline(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr])
range = parse_util_process_extent(current_buffer, current_cursor_pos, None);
}
TextScope::Token => {
parse_util_token_extent(current_buffer, current_cursor_pos, &mut range, None);
(range, _) = parse_util_token_extent(current_buffer, current_cursor_pos);
}
}
}

View File

@ -475,13 +475,7 @@ pub fn complete(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) ->
Some(param) => param,
};
let mut token = 0..0;
parse_util_token_extent(
&do_complete_param,
do_complete_param.len(),
&mut token,
None,
);
let (token, _) = parse_util_token_extent(&do_complete_param, do_complete_param.len());
// Create a scoped transient command line, so that builtin_commandline will see our
// argument, not the reader buffer.

View File

@ -437,30 +437,20 @@ fn job_or_process_extent(
}
/// Find the beginning and end of the token under the cursor and the token before the current token.
/// Any combination of tok_begin, tok_end, prev_begin and prev_end may be null.
///
/// \param buff the string to search for subshells
/// \param cursor_pos the position of the cursor
/// \param tok_begin the start of the current token
/// \param tok_end the end of the current token
/// \param prev_begin the start o the token before the current token
/// \param prev_end the end of the token before the current token
pub fn parse_util_token_extent(
buff: &wstr,
cursor_pos: usize,
out_tok: &mut ops::Range<usize>,
mut out_prev: Option<&mut ops::Range<usize>>,
) {
pub fn parse_util_token_extent(buff: &wstr, cursor_pos: usize) -> (Range<usize>, Range<usize>) {
let cmdsubst_range = parse_util_cmdsubst_extent(buff, cursor_pos);
let cmdsubst_begin = cmdsubst_range.start;
// pos is equivalent to cursor_pos within the range of the command substitution {begin, end}.
let offset_within_cmdsubst = cursor_pos - cmdsubst_range.start;
let mut a = cmdsubst_begin + offset_within_cmdsubst;
let mut b = a;
let mut pa = a;
let mut pb = pa;
let mut cur_begin = cmdsubst_begin + offset_within_cmdsubst;
let mut cur_end = cur_begin;
let mut prev_begin = cur_begin;
let mut prev_end = cur_begin;
assert!(cmdsubst_begin <= buff.len());
assert!(cmdsubst_range.end <= buff.len());
@ -477,31 +467,30 @@ pub fn parse_util_token_extent(
// Cursor was before beginning of this token, means that the cursor is between two tokens,
// so we set it to a zero element string and break.
if tok_begin > offset_within_cmdsubst {
a = cmdsubst_begin + offset_within_cmdsubst;
b = a;
cur_begin = cmdsubst_begin + offset_within_cmdsubst;
cur_end = cur_begin;
break;
}
// If cursor is inside the token, this is the token we are looking for. If so, set a and b
// and break.
// If cursor is inside the token, this is the token we are looking for. If so, set
// cur_begin and cur_end and break.
if token.type_ == TokenType::string && tok_end >= offset_within_cmdsubst {
a = cmdsubst_begin + token.offset();
b = a + token.length();
cur_begin = cmdsubst_begin + token.offset();
cur_end = cur_begin + token.length();
break;
}
// Remember previous string token.
if token.type_ == TokenType::string {
pa = cmdsubst_begin + token.offset();
pb = pa + token.length();
prev_begin = cmdsubst_begin + token.offset();
prev_end = prev_begin + token.length();
}
}
*out_tok = a..b;
out_prev.as_mut().map(|prev| **prev = pa..pb);
assert!(pa <= buff.len());
assert!(pb >= pa);
assert!(pb <= buff.len());
assert!(prev_begin <= buff.len());
assert!(prev_end >= prev_begin);
assert!(prev_end <= buff.len());
(cur_begin..cur_end, prev_begin..prev_end)
}
/// Get the line number at the specified character offset.

View File

@ -1457,8 +1457,7 @@ pub fn combine_command_and_autosuggestion(
// Here we do something funny: if the last token of the command line contains any uppercase
// characters, we use its case. Otherwise we use the case of the autosuggestion. This
// is an idea from issue #335.
let mut tok = 0..0;
parse_util_token_extent(cmdline, cmdline.len() - 1, &mut tok, None);
let (tok, _) = parse_util_token_extent(cmdline, cmdline.len() - 1);
let last_token_contains_uppercase = cmdline[tok].chars().any(|c| c.is_uppercase());
if !last_token_contains_uppercase {
// Use the autosuggestion's case.
@ -1856,8 +1855,7 @@ impl ReaderData {
fn replace_current_token(&mut self, new_token: WString) {
// Find current token.
let (elt, el) = self.active_edit_line();
let mut token_range = 0..0;
parse_util_token_extent(el.text(), el.position(), &mut token_range, None);
let (token_range, _) = parse_util_token_extent(el.text(), el.position());
self.replace_substring(elt, token_range, new_token);
}
@ -2934,8 +2932,7 @@ impl<'a> Reader<'a> {
let el = &self.data.command_line;
if mode == SearchMode::Token {
// Searching by token.
let mut token_range = 0..0;
parse_util_token_extent(el.text(), el.position(), &mut token_range, None);
let (token_range, _) = parse_util_token_extent(el.text(), el.position());
self.data.history_search.reset_to_mode(
el.text()[token_range.clone()].to_owned(),
self.history.clone(),
@ -3402,15 +3399,13 @@ impl<'a> Reader<'a> {
let (elt, el) = self.active_edit_line();
let text = el.text();
let mut tok = 0..0;
let mut prev_tok = 0..0;
parse_util_token_extent(text, el.position(), &mut tok, Some(&mut prev_tok));
let (mut tok, mut prev_tok) = parse_util_token_extent(text, el.position());
// In case we didn't find a token at or after the cursor...
if tok.start == el.len() {
// ...retry beginning from the previous token.
let pos = prev_tok.end;
parse_util_token_extent(text, pos, &mut tok, Some(&mut prev_tok));
(tok, prev_tok) = parse_util_token_extent(text, pos);
}
// Make sure we have two tokens.
@ -3792,9 +3787,7 @@ impl<'a> Reader<'a> {
return None;
}
let mut tok = 0..0;
let mut prev_tok = 0..0;
parse_util_token_extent(el.text(), el.position(), &mut tok, Some(&mut prev_tok));
let (tok, prev_tok) = parse_util_token_extent(el.text(), el.position());
// if we are at the start of a token, go back one
let new_position = if tok.start == pos {
@ -6012,8 +6005,7 @@ pub fn completion_apply_to_command_line(
if do_replace_token {
let mut move_cursor = 0;
let mut range = 0..0;
parse_util_token_extent(command_line, cursor_pos, &mut range, None);
let (range, _) = parse_util_token_extent(command_line, cursor_pos);
let mut sb = command_line[..range.start].to_owned();
@ -6049,8 +6041,7 @@ pub fn completion_apply_to_command_line(
let mut quote = None;
let replaced = if do_escape {
let mut tok = 0..0;
parse_util_token_extent(command_line, cursor_pos, &mut tok, None);
let (tok, _) = parse_util_token_extent(command_line, cursor_pos);
// Find the last quote in the token to complete.
let mut have_token = false;
if tok.contains(&cursor_pos) || cursor_pos == tok.end {
@ -6155,13 +6146,8 @@ impl<'a> Reader<'a> {
// Figure out the extent of the token within the command substitution. Note we
// pass cmdsub_begin here, not buff.
let mut token_range = 0..0;
parse_util_token_extent(
&el.text()[cmdsub_range.clone()],
position_in_cmdsub,
&mut token_range,
None,
);
let (mut token_range, _) =
parse_util_token_extent(&el.text()[cmdsub_range.clone()], position_in_cmdsub);
let position_in_token = position_in_cmdsub - token_range.start;
// Hack: the token may extend past the end of the command substitution, e.g. in