From 4f3d6427ce021ed509907c4a30bf2e63b5b4a31d Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sun, 12 Jan 2025 14:12:26 +0100 Subject: [PATCH] Fix regression causing crash in "commandline -j" Commit 3fcc6482cb (Fix parse_util_process_extent including too much on the left, 2024-12-24) changed the process extent based on the observation that "A\n\n\nB" comprises three tokens with ranges 0..1, 1..2 and 4..5. Prior to that commit, the second process extent was 2..5, which seems a bit weird because it includes newlines. Weirdness aside, the real reason for changing it was this snippet in the autosuggestion performer, where we compute the process extent around cursor, and check if the line at process start matches the cached search string. // Search history for a matching item unless this line is not a continuation line or quoted. if range_of_line_at_cursor( &command_line, parse_util_process_extent(&command_line, cursor_pos, None).start, ) == search_string_range Given "A\n\n\nB" and cursor_pos=1 commit 3fcc6482cb changed the output from 2..5 to 4..5. This brings problems: 1. leading spaces will not be included (which is probably inconsequential but still ugly). 2. the specified cursor position is not included in the given range. We could paper over 2 by computing min(cursor_pos) but that would leave 1. For now let's revert and solve the autosuggestion issue in a less brittle way. --- src/parse_util.rs | 7 +------ src/reader.rs | 15 ++++++++++----- src/tests/parse_util.rs | 3 ++- tests/checks/tmux-commandline.fish | 18 +++++++++++++++--- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/parse_util.rs b/src/parse_util.rs index 60f98f948..1423edd77 100644 --- a/src/parse_util.rs +++ b/src/parse_util.rs @@ -401,7 +401,6 @@ fn job_or_process_extent( let pos = cursor_pos - cmdsub_range.start; let mut result = cmdsub_range.clone(); - let mut found_start = false; for token in Tokenizer::new( &buff[cmdsub_range.clone()], TOK_ACCEPT_UNFINISHED | TOK_SHOW_COMMENTS, @@ -423,17 +422,13 @@ fn job_or_process_extent( result.end = cmdsub_range.start + tok_begin; } else { // Statement at cursor might start after this token. - found_start = false; + result.start = cmdsub_range.start + tok_begin + token.length(); out_tokens.as_mut().map(|tokens| tokens.clear()); } continue; // Do not add this to tokens } _ => (), } - if !found_start { - result.start = cmdsub_range.start + tok_begin; - found_start = true; - } out_tokens.as_mut().map(|tokens| tokens.push(token)); } result diff --git a/src/reader.rs b/src/reader.rs index a3b6512fa..89b5b4eeb 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -4646,11 +4646,16 @@ fn get_autosuggestion_performer( }; // Search history for a matching item unless this line is not a continuation line or quoted. - if range_of_line_at_cursor( - &command_line, - parse_util_process_extent(&command_line, cursor_pos, None).start, - ) == search_string_range - { + if { + let mut tokens = vec![]; + parse_util_process_extent(&command_line, cursor_pos, Some(&mut tokens)); + tokens + .first() + .map(|tok| { + range_of_line_at_cursor(&command_line, tok.offset()) == search_string_range + }) + .unwrap_or_default() + } { let mut searcher = HistorySearch::new_with_type( history, search_string.to_owned(), diff --git a/src/tests/parse_util.rs b/src/tests/parse_util.rs index 879459707..b41a94649 100644 --- a/src/tests/parse_util.rs +++ b/src/tests/parse_util.rs @@ -102,7 +102,8 @@ fn test_parse_util_process_extent() { }; } validate!("for file in (path base\necho", 22, 13..22); - validate!("begin\n\n\nec", 10, 8..10); + validate!("begin\n\n\nec", 10, 6..10); + validate!("begin; echo; end", 12, 12..16); } #[test] diff --git a/tests/checks/tmux-commandline.fish b/tests/checks/tmux-commandline.fish index 4912ec715..8aeae75e4 100644 --- a/tests/checks/tmux-commandline.fish +++ b/tests/checks/tmux-commandline.fish @@ -3,6 +3,11 @@ # Somehow $LINES is borked on NetBSD? #REQUIRES: test $(uname) != NetBSD +set -g isolated_tmux_fish_extra_args -C ' + bind ctrl-q "functions --erase fish_right_prompt" "commandline \'\'" clear-screen + set -g fish_autosuggestion_enabled 0 + bind ctrl-g "__fish_echo commandline --current-job" +' isolated-tmux-start isolated-tmux send-keys 'echo LINES $LINES' Enter @@ -33,9 +38,7 @@ isolated-tmux capture-pane -p # CHECK: scroll_here # Soft-wrapped commandline with omitted right prompt. -isolated-tmux send-keys C-c -tmux-sleep -isolated-tmux send-keys C-l ' +isolated-tmux send-keys C-q ' function fish_right_prompt echo right-prompt end @@ -47,3 +50,12 @@ isolated-tmux capture-pane -p | sed 1,5d # CHECK: 000000000000000 # CHECK: 00000000000000000000000000000000000000000000000000000000000000000000000000000000 # CHECK: prompt {{\d+}}> right-prompt + +isolated-tmux send-keys C-q 'echo | echo\;' M-Enter 'another job' C-b C-b C-g +tmux-sleep +isolated-tmux capture-pane -p +# CHECK: prompt {{\d+}}> echo | echo; +# CHECK: another job +# CHECK: another job +# CHECK: prompt {{\d+}}> echo | echo; +# CHECK: another job