implement selection update mechanism

pull/10905/head
Sam Vente 6 months ago
parent 2da81b254b
commit d1e2bff16b
No known key found for this signature in database

@ -6125,8 +6125,8 @@ fn extend_to_word(cx: &mut Context) {
jump_to_word(cx, Movement::Extend) jump_to_word(cx, Movement::Extend)
} }
fn read_from_register(editor: &Editor, reg: char) -> Option<RegisterValues> { fn read_from_register(editor: &mut Editor, reg: char) -> Option<RegisterValues> {
editor.registers.read(reg, &editor) editor.registers.read(reg, &*editor)
} }
fn jump_to_label(cx: &mut Context, labels: Vec<Range>, behaviour: Movement) { fn jump_to_label(cx: &mut Context, labels: Vec<Range>, behaviour: Movement) {

@ -467,14 +467,21 @@ fn register_mark(
let ranges_str = ranges let ranges_str = ranges
.iter() .iter()
.map(|r| r.to_string()) .map(|r| r.to_string())
.collect::<Vec<String>>() .collect::<Vec<String>>();
.join(",");
// we have to take because of cell
let history = doc.history.take();
let current_history_point = history.current_revision();
doc.history.replace(history);
let mut register_val = vec![
format!("{}", doc.id()),
format!("{}", current_history_point),
];
register_val.extend(ranges_str);
cx.editor cx.editor
.registers .registers
.write( .write(register_name, register_val)
register_name,
vec![format!("{}:{}", doc.id(), ranges_str.to_string())],
)
.unwrap(); .unwrap();
cx.editor cx.editor
@ -482,30 +489,19 @@ fn register_mark(
Ok(()) Ok(())
} }
fn goto_mark( fn parse_mark_register_contents(
cx: &mut compositor::Context, registers_vals: Option<RegisterValues>,
args: &[Cow<str>], ) -> Result<(DocumentId, usize, Selection), String> {
event: PromptEvent, match registers_vals {
) -> anyhow::Result<()> { Some(rv) => {
if event != PromptEvent::Validate { let mut rv_iter = rv.into_iter();
return Ok(()); let doc_id_str = rv_iter.next().unwrap().into_owned();
}; let doc_id: DocumentId = doc_id_str.try_into().unwrap();
let register_name: char = args let history_rev_str = rv_iter.next().unwrap().into_owned();
.first() let history_rev: usize = history_rev_str.parse().unwrap();
.map_or_else( let mut ranges = rv_iter
|| cx.editor.selected_register, .map(|tup| {
|s| s.as_ref().chars().next(), let s = tup.into_owned();
)
.unwrap_or('^');
let registers_vals = read_from_register(cx.editor, register_name);
let blurb = registers_vals
.unwrap()
.into_iter()
.next()
.map(|c| c.into_owned());
match blurb {
Some(s) => {
let doc_id_parser = seq!(take_until(|c| c == ':'), ":");
let range_parser = seq!( let range_parser = seq!(
"(", "(",
take_until(|c| c == ','), take_until(|c| c == ','),
@ -513,14 +509,8 @@ fn goto_mark(
take_until(|c| c == ')'), take_until(|c| c == ')'),
")" ")"
); );
let multiple_ranges_parser = sep(range_parser, ","); let (_, (_, anchor_str, _, head_str, _)) = range_parser.parse(&s).unwrap();
let (tail, (doc_id_str, _)) = doc_id_parser.parse(&s).unwrap(); let anchor: usize = <usize as FromStr>::from_str(anchor_str).unwrap().clone();
let (_tail, v) = multiple_ranges_parser.parse(tail).unwrap();
let mut ranges = v
.iter()
.map(|tup| {
let (_, anchor_str, _, head_str, _) = tup;
let anchor: usize = <usize as FromStr>::from_str(anchor_str).unwrap();
let head: usize = <usize as FromStr>::from_str(head_str).unwrap(); let head: usize = <usize as FromStr>::from_str(head_str).unwrap();
Range { Range {
anchor, anchor,
@ -528,21 +518,54 @@ fn goto_mark(
old_visual_position: None, old_visual_position: None,
} }
}) })
.rev();
// reverse the iterators so the first range will end up as the primary when we push them // reverse the iterators so the first range will end up as the primary when we push them
.rev();
let doc_id: DocumentId = doc_id_str.try_into().unwrap();
cx.editor.switch(doc_id, Action::Replace);
let (view, doc) = current!(cx.editor);
let last_range = ranges.next().unwrap(); // there is always at least one range let last_range = ranges.next().unwrap(); // there is always at least one range
let mut selection = Selection::from(last_range); let mut selection = Selection::from(last_range);
for r in ranges { for r in ranges {
selection = selection.push(r); selection = selection.push(r);
} }
doc.set_selection(view.id, selection); Ok((doc_id, history_rev, selection))
}
None => Err("Could not parse registry content".to_string()), // I can't figure out how to set status line here because of borrow issues :(
} }
None => (), }
fn get_revisions_to_apply(doc: &mut Document, history_rev: usize) -> Option<Transaction> {
let history = doc.history.take();
let revisions_to_apply = history.changes_since(history_rev);
doc.history.replace(history);
revisions_to_apply
}
fn goto_mark(
cx: &mut compositor::Context,
args: &[Cow<str>],
event: PromptEvent,
) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
return Ok(());
}; };
let register_name: char = args
.first()
.map_or_else(
|| cx.editor.selected_register,
|s| s.as_ref().chars().next(),
)
.unwrap_or('^');
let registers_vals = read_from_register(cx.editor, register_name);
let (doc_id, history_rev, mut selection) =
parse_mark_register_contents(registers_vals).unwrap();
cx.editor.switch(doc_id, Action::Replace);
let (view, doc) = current!(cx.editor);
let revisions_to_apply = get_revisions_to_apply(doc, history_rev);
selection = match revisions_to_apply {
Some(t) => selection.map(t.changes()),
None => selection,
};
doc.set_selection(view.id, selection);
Ok(()) Ok(())
} }

@ -38,6 +38,14 @@ impl TryFrom<&str> for DocumentId {
Ok(Self(value.parse::<NonZeroUsize>()?)) Ok(Self(value.parse::<NonZeroUsize>()?))
} }
} }
impl TryFrom<String> for DocumentId {
type Error = ParseIntError;
fn try_from(value: String) -> Result<Self, Self::Error> {
Ok(Self(value.parse::<NonZeroUsize>()?))
}
}
impl std::fmt::Display for DocumentId { impl std::fmt::Display for DocumentId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{}", self.0)) f.write_fmt(format_args!("{}", self.0))

Loading…
Cancel
Save