diff --git a/src/builtins/read.rs b/src/builtins/read.rs index 9f7f4e74d..cfeec69b8 100644 --- a/src/builtins/read.rs +++ b/src/builtins/read.rs @@ -39,7 +39,7 @@ struct Options { prompt: Option, prompt_str: Option, right_prompt: WString, - commandline: WString, + commandline: Option, // If a delimiter was given. Used to distinguish between the default // empty string and a given empty delimiter. delimiter: Option, @@ -100,7 +100,7 @@ fn parse_cmd_opts( opts.array = true; } 'c' => { - opts.commandline = w.woptarg.unwrap().to_owned(); + opts.commandline = Some(w.woptarg.unwrap().to_owned()); } 'd' => { opts.delimiter = Some(w.woptarg.unwrap().to_owned()); @@ -207,7 +207,7 @@ fn read_interactive( silent: bool, prompt: &wstr, right_prompt: &wstr, - commandline: &wstr, + commandline: &Option, inputfd: RawFd, ) -> BuiltinResult { let mut exit_res = Ok(SUCCESS); @@ -238,7 +238,9 @@ fn read_interactive( s.readonly_commandline = false; }) }); - commandline_set_buffer(parser, Some(commandline.to_owned()), None); + if let Some(commandline) = commandline { + commandline_set_buffer(parser, Some(commandline.clone()), None); + } let mline = { let _interactive = parser.push_scope(|s| s.is_interactive = true); diff --git a/src/reader.rs b/src/reader.rs index b9eeaac94..00b44b703 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -317,11 +317,12 @@ pub fn reader_push<'a>(parser: &'a Parser, history_name: &wstr, conf: ReaderConf assert_is_main_thread(); let hist = History::with_name(history_name); hist.resolve_pending(); - let data = ReaderData::new(hist, conf); + let is_top_level = reader_data_stack().is_empty(); + let data = ReaderData::new(hist, conf, is_top_level); reader_data_stack().push(data); let data = current_data().unwrap(); data.command_line_changed(EditableLineTag::Commandline, AutosuggestionUpdate::Remove); - if reader_data_stack().len() == 1 { + if is_top_level { reader_interactive_init(parser); } Reader { data, parser } @@ -1201,12 +1202,18 @@ fn reader_received_sighup() -> bool { } impl ReaderData { - fn new(history: Arc, conf: ReaderConfig) -> Pin> { + fn new(history: Arc, conf: ReaderConfig, is_top_level: bool) -> Pin> { let input_data = InputData::new(conf.inputfd); + let mut command_line = EditableLine::default(); + if is_top_level { + let state = commandline_state_snapshot(); + command_line.push_edit(Edit::new(0..0, state.text.clone()), false); + command_line.set_position(state.cursor_pos); + } Pin::new(Box::new(Self { canary: Rc::new(()), conf, - command_line: Default::default(), + command_line, command_line_transient_edit: None, rendered_layout: Default::default(), autosuggestion: Default::default(), diff --git a/tests/pexpects/commandline.py b/tests/pexpects/commandline.py index a3ccec121..8e0956b9d 100644 --- a/tests/pexpects/commandline.py +++ b/tests/pexpects/commandline.py @@ -102,6 +102,18 @@ send(control("k")) sendline('echo "process extent is [$tmp]"') expect_str("process extent is [echo process # comment]") +sendline( + """$fish -C 'commandline "sq 2; exit"; commandline --cursor 1; commandline -i e'""" +) +expect_str("seq 2") +send("\r") +expect_str("1\r\n2\r\n") + +sendline("""$fish -C 'commandline 123; read'""") +expect_str("read> 123") +sendline("456; exit") +expect_str("123456") + # DISABLED because it keeps failing under ASAN # sendline(r"bind ctrl-b 'set tmp (commandline --current-process | count)'") # sendline(r'commandline "echo line1 \\" "# comment" "line2"')