strop_engine/editor/normal/
preview.rs1use strop_core::Range;
6use strop_grammar::{self as grammar, Parse};
7
8use crate::editor::Editor;
9
10impl Editor {
11 pub fn preview(&self) -> Result<Option<(Vec<Range>, String)>, String> {
17 let Some((command, cursors)) = self.preview_command()? else {
18 return Ok(None);
19 };
20 if command.op.is_none()
21 || (self.resolution_is_large(&command) && !self.resolution_ready(&command, &cursors))
22 {
23 return Ok(None);
24 }
25 let resolved = self.resolved_many(&command, &cursors)?;
26 let Some(Some(primary)) = resolved.first() else {
27 return Ok(None);
28 };
29 let Some(plan) = self.resolved_plan(&command, &cursors)? else {
30 return Ok(None);
31 };
32 Ok(Some((
33 plan.targets.iter().map(|target| target.range).collect(),
34 primary.spec.clone(),
35 )))
36 }
37
38 pub(crate) fn prepare_resolution_preview(&mut self) {
39 if self.resolution.blocked()
40 || self
41 .pending
42 .prompt()
43 .is_some_and(|prompt| prompt.search().is_some())
44 {
45 return;
46 }
47 match self.preview_command() {
48 Ok(Some((command, cursors))) => {
49 self.defer_resolution(
50 &command,
51 cursors,
52 super::super::resolution::ResolutionPurpose::Preview,
53 );
54 }
55 Ok(None) => self.resolution.cancel_preview(),
56 Err(error) => {
57 self.resolution.cancel_preview();
58 self.message = error;
59 }
60 }
61 }
62
63 fn preview_command(&self) -> Result<Option<(grammar::Command, Vec<usize>)>, String> {
64 if let Some(prompt) = self.pending.prompt() {
65 let Some((origin, state)) = prompt.search() else {
66 return Ok(None);
67 };
68 if state.op.is_none() || !self.pending_origin_valid(origin) {
69 return Ok(None);
70 }
71 let Some(command) = self.search_prompt_command(prompt, false)? else {
72 return Ok(None);
73 };
74 Ok(Some((command, origin.pane.sels.heads())))
75 } else {
76 let Some((operator, motion)) = self.walker.op_motion() else {
77 return Ok(None);
78 };
79 let keys = operator.key().to_string() + motion;
80 let mut command = match grammar::parse(&keys) {
81 Parse::Complete(command) => command,
82 Parse::QueryError(error) => return Err(error.to_string()),
83 Parse::Incomplete | Parse::Invalid => return Ok(None),
84 };
85 command.count = self.walker.state.count();
86 command.register = self.walker.state.register;
87 Ok(Some((command, self.all_cursors())))
88 }
89 }
90}