Enter a repl loop
(vm: &VirtualMachine, scope: Scope)
| 107 | |
| 108 | /// Enter a repl loop |
| 109 | pub fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> { |
| 110 | let mut repl = Readline::new(helper::ShellHelper::new(vm, scope.globals.clone())); |
| 111 | let mut full_input = String::new(); |
| 112 | |
| 113 | // Retrieve a `history_path_str` dependent on the OS |
| 114 | let repl_history_path = match dirs::config_dir() { |
| 115 | Some(mut path) => { |
| 116 | path.push("rustpython"); |
| 117 | path.push("repl_history.txt"); |
| 118 | path |
| 119 | } |
| 120 | None => ".repl_history.txt".into(), |
| 121 | }; |
| 122 | |
| 123 | if repl.load_history(&repl_history_path).is_err() { |
| 124 | println!("No previous history."); |
| 125 | } |
| 126 | |
| 127 | // We might either be waiting to know if a block is complete, or waiting to know if a multiline |
| 128 | // statement is complete. In the former case, we need to ensure that we read one extra new line |
| 129 | // to know that the block is complete. In the latter, we can execute as soon as the statement is |
| 130 | // valid. |
| 131 | let mut continuing_block = false; |
| 132 | let mut continuing_line = false; |
| 133 | |
| 134 | loop { |
| 135 | let prompt_name = if continuing_block || continuing_line { |
| 136 | "ps2" |
| 137 | } else { |
| 138 | "ps1" |
| 139 | }; |
| 140 | let prompt = vm |
| 141 | .sys_module |
| 142 | .get_attr(prompt_name, vm) |
| 143 | .and_then(|prompt| prompt.str(vm)); |
| 144 | let prompt = match prompt { |
| 145 | Ok(ref s) => s.expect_str(), |
| 146 | Err(_) => "", |
| 147 | }; |
| 148 | |
| 149 | continuing_line = false; |
| 150 | let result = match repl.readline(prompt) { |
| 151 | ReadlineResult::Line(line) => { |
| 152 | #[cfg(debug_assertions)] |
| 153 | debug!("You entered {line:?}"); |
| 154 | |
| 155 | repl.add_history_entry(line.trim_end()).unwrap(); |
| 156 | |
| 157 | let empty_line_given = line.is_empty(); |
| 158 | |
| 159 | if full_input.is_empty() { |
| 160 | full_input = line; |
| 161 | } else { |
| 162 | full_input.push_str(&line); |
| 163 | } |
| 164 | full_input.push('\n'); |
| 165 | |
| 166 | match shell_exec( |
no test coverage detected