Allow multi-cursor 'smart' goto-file

This commit is contained in:
emilylime 2024-11-18 18:37:41 +02:00
parent 73deabaa40
commit ea98f84098

View File

@ -1265,15 +1265,14 @@ fn goto_file_impl(cx: &mut Context, action: Action) {
let (view, doc) = current_ref!(cx.editor); let (view, doc) = current_ref!(cx.editor);
let text = doc.text(); let text = doc.text();
let selections = doc.selection(view.id); let selections = doc.selection(view.id);
let primary = selections.primary();
let rel_path = doc let rel_path = doc
.relative_path() .relative_path()
.map(|path| path.parent().unwrap().to_path_buf()) .map(|path| path.parent().unwrap().to_path_buf())
.unwrap_or_default(); .unwrap_or_default();
let paths: Vec<_> = if selections.len() == 1 && primary.len() == 1 { let paths: Vec<_> = if selections.iter().all(|r| r.len() == 1) {
// Secial case: if there is only one one-width selection, try to detect the // Secial case: if all selections are only one-wide, try to detect the path under the
// path under the cursor. // cursor.
let is_valid_path_char = |c: &char| { let is_valid_path_char = |c: &char| {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
let valid_chars = &[ let valid_chars = &[
@ -1286,34 +1285,39 @@ fn goto_file_impl(cx: &mut Context, action: Action) {
valid_chars.contains(c) || c.is_alphabetic() || c.is_numeric() valid_chars.contains(c) || c.is_alphabetic() || c.is_numeric()
}; };
let cursor_pos = primary.cursor(text.slice(..)); selections
let pre_cursor_pos = cursor_pos.saturating_sub(1); .iter()
let post_cursor_pos = cursor_pos + 1; .map(|sel| {
let start_pos = if is_valid_path_char(&text.char(cursor_pos)) { let cursor_pos = sel.cursor(text.slice(..));
cursor_pos let pre_cursor_pos = cursor_pos.saturating_sub(1);
} else if is_valid_path_char(&text.char(pre_cursor_pos)) { let post_cursor_pos = cursor_pos + 1;
pre_cursor_pos let start_pos = if is_valid_path_char(&text.char(cursor_pos)) {
} else { cursor_pos
post_cursor_pos } else if is_valid_path_char(&text.char(pre_cursor_pos)) {
}; pre_cursor_pos
} else {
post_cursor_pos
};
let prefix_len = text let prefix_len = text
.chars_at(start_pos) .chars_at(start_pos)
.reversed() .reversed()
.take_while(is_valid_path_char) .take_while(is_valid_path_char)
.count(); .count();
let postfix_len = text let postfix_len = text
.chars_at(start_pos) .chars_at(start_pos)
.take_while(is_valid_path_char) .take_while(is_valid_path_char)
.count(); .count();
let path: String = text let path: String = text
.slice((start_pos - prefix_len)..(start_pos + postfix_len)) .slice((start_pos - prefix_len)..(start_pos + postfix_len))
.into(); .into();
log::debug!("goto_file auto-detected path: {}", path);
vec![path] log::debug!("goto_file auto-detected path: {}", path);
path
})
.collect()
} else { } else {
// Otherwise use each selection, trimmed. // Otherwise use each selection, trimmed.
selections selections