Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--Cargo.lock1
-rw-r--r--helix-core/src/selection.rs7
-rw-r--r--helix-term/Cargo.toml1
-rw-r--r--helix-term/src/application.rs11
-rw-r--r--helix-term/src/args.rs31
-rw-r--r--helix-term/src/main.rs6
-rw-r--r--helix-term/tests/test/helpers.rs5
7 files changed, 45 insertions, 17 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4666c1d0..2419fa9b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1454,6 +1454,7 @@ dependencies = [
"helix-vcs",
"helix-view",
"ignore",
+ "indexmap",
"indoc",
"libc",
"log",
diff --git a/helix-core/src/selection.rs b/helix-core/src/selection.rs
index 76de6362..a134a06e 100644
--- a/helix-core/src/selection.rs
+++ b/helix-core/src/selection.rs
@@ -619,7 +619,6 @@ impl Selection {
self
}
- // TODO: consume an iterator or a vec to reduce allocations?
#[must_use]
pub fn new(ranges: SmallVec<[Range; 1]>, primary_index: usize) -> Self {
assert!(!ranges.is_empty());
@@ -721,6 +720,12 @@ impl IntoIterator for Selection {
}
}
+impl FromIterator<Range> for Selection {
+ fn from_iter<T: IntoIterator<Item = Range>>(ranges: T) -> Self {
+ Self::new(ranges.into_iter().collect(), 0)
+ }
+}
+
impl From<Range> for Selection {
fn from(range: Range) -> Self {
Self {
diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml
index dffee147..da85a563 100644
--- a/helix-term/Cargo.toml
+++ b/helix-term/Cargo.toml
@@ -61,6 +61,7 @@ tokio-stream = "0.1"
futures-util = { version = "0.3", features = ["std", "async-await"], default-features = false }
arc-swap = { version = "1.7.1" }
termini = "1"
+indexmap = "2.5"
# Logging
fern = "0.7"
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs
index 36cb295c..00aa7390 100644
--- a/helix-term/src/application.rs
+++ b/helix-term/src/application.rs
@@ -1,6 +1,6 @@
use arc_swap::{access::Map, ArcSwap};
use futures_util::Stream;
-use helix_core::{diagnostic::Severity, pos_at_coords, syntax, Selection};
+use helix_core::{diagnostic::Severity, pos_at_coords, syntax, Range, Selection};
use helix_lsp::{
lsp::{self, notification::Notification},
util::lsp_range_to_range,
@@ -210,8 +210,13 @@ impl Application {
// opened last is focused on.
let view_id = editor.tree.focus;
let doc = doc_mut!(editor, &doc_id);
- let pos = Selection::point(pos_at_coords(doc.text().slice(..), pos, true));
- doc.set_selection(view_id, pos);
+ let selection = pos
+ .into_iter()
+ .map(|coords| {
+ Range::point(pos_at_coords(doc.text().slice(..), coords, true))
+ })
+ .collect();
+ doc.set_selection(view_id, selection);
}
}
diff --git a/helix-term/src/args.rs b/helix-term/src/args.rs
index 853c1576..9b1b4409 100644
--- a/helix-term/src/args.rs
+++ b/helix-term/src/args.rs
@@ -1,6 +1,7 @@
use anyhow::Result;
use helix_core::Position;
use helix_view::tree::Layout;
+use indexmap::IndexMap;
use std::path::{Path, PathBuf};
#[derive(Default)]
@@ -16,7 +17,7 @@ pub struct Args {
pub verbosity: u64,
pub log_file: Option<PathBuf>,
pub config_file: Option<PathBuf>,
- pub files: Vec<(PathBuf, Position)>,
+ pub files: IndexMap<PathBuf, Vec<Position>>,
pub working_directory: Option<PathBuf>,
}
@@ -26,6 +27,18 @@ impl Args {
let mut argv = std::env::args().peekable();
let mut line_number = 0;
+ let mut insert_file_with_position = |file_with_position: &str| {
+ let (filename, position) = parse_file(file_with_position);
+
+ // Before setting the working directory, resolve all the paths in args.files
+ let filename = helix_stdx::path::canonicalize(filename);
+
+ args.files
+ .entry(filename)
+ .and_modify(|positions| positions.push(position))
+ .or_insert_with(|| vec![position]);
+ };
+
argv.next(); // skip the program, we don't care about that
while let Some(arg) = argv.next() {
@@ -92,21 +105,25 @@ impl Args {
arg if arg.starts_with('+') => {
match arg[1..].parse::<usize>() {
Ok(n) => line_number = n.saturating_sub(1),
- _ => args.files.push(parse_file(arg)),
+ _ => insert_file_with_position(arg),
};
}
- arg => args.files.push(parse_file(arg)),
+ arg => insert_file_with_position(arg),
}
}
// push the remaining args, if any to the files
for arg in argv {
- args.files.push(parse_file(&arg));
+ insert_file_with_position(&arg);
}
- if let Some(file) = args.files.first_mut() {
- if line_number != 0 {
- file.1.row = line_number;
+ if line_number != 0 {
+ if let Some(first_position) = args
+ .files
+ .first_mut()
+ .and_then(|(_, positions)| positions.first_mut())
+ {
+ first_position.row = line_number;
}
}
diff --git a/helix-term/src/main.rs b/helix-term/src/main.rs
index 385a0406..31ab85cf 100644
--- a/helix-term/src/main.rs
+++ b/helix-term/src/main.rs
@@ -40,7 +40,7 @@ fn main() -> Result<()> {
#[tokio::main]
async fn main_impl() -> Result<i32> {
- let mut args = Args::parse_args().context("could not parse arguments")?;
+ let args = Args::parse_args().context("could not parse arguments")?;
helix_loader::initialize_config_file(args.config_file.clone());
helix_loader::initialize_log_file(args.log_file.clone());
@@ -114,10 +114,6 @@ FLAGS:
setup_logging(args.verbosity).context("failed to initialize logging")?;
- // Before setting the working directory, resolve all the paths in args.files
- for (path, _) in &mut args.files {
- *path = helix_stdx::path::canonicalize(&*path);
- }
// NOTE: Set the working directory early so the correct configuration is loaded. Be aware that
// Application::new() depends on this logic so it must be updated if this changes.
if let Some(path) = &args.working_directory {
diff --git a/helix-term/tests/test/helpers.rs b/helix-term/tests/test/helpers.rs
index 70b3f402..ef910852 100644
--- a/helix-term/tests/test/helpers.rs
+++ b/helix-term/tests/test/helpers.rs
@@ -345,7 +345,10 @@ impl AppBuilder {
path: P,
pos: Option<helix_core::Position>,
) -> Self {
- self.args.files.push((path.into(), pos.unwrap_or_default()));
+ self.args
+ .files
+ .insert(path.into(), vec![pos.unwrap_or_default()]);
+
self
}