aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src/args.rs
diff options
context:
space:
mode:
Diffstat (limited to 'helix-term/src/args.rs')
-rw-r--r--helix-term/src/args.rs45
1 files changed, 40 insertions, 5 deletions
diff --git a/helix-term/src/args.rs b/helix-term/src/args.rs
index 40113db9..247d5b32 100644
--- a/helix-term/src/args.rs
+++ b/helix-term/src/args.rs
@@ -1,5 +1,6 @@
use anyhow::{Error, Result};
-use std::path::PathBuf;
+use helix_core::Position;
+use std::path::{Path, PathBuf};
#[derive(Default)]
pub struct Args {
@@ -7,7 +8,7 @@ pub struct Args {
pub display_version: bool,
pub load_tutor: bool,
pub verbosity: u64,
- pub files: Vec<PathBuf>,
+ pub files: Vec<(PathBuf, Position)>,
}
impl Args {
@@ -41,15 +42,49 @@ impl Args {
}
}
}
- arg => args.files.push(PathBuf::from(arg)),
+ arg => args.files.push(parse_file(arg)),
}
}
// push the remaining args, if any to the files
- for filename in iter {
- args.files.push(PathBuf::from(filename));
+ for arg in iter {
+ args.files.push(parse_file(arg));
}
Ok(args)
}
}
+
+/// Parse arg into [`PathBuf`] and position.
+pub(crate) fn parse_file(s: &str) -> (PathBuf, Position) {
+ let def = || (PathBuf::from(s), Position::default());
+ if Path::new(s).exists() {
+ return def();
+ }
+ split_path_row_col(s)
+ .or_else(|| split_path_row(s))
+ .unwrap_or_else(def)
+}
+
+/// Split file.rs:10:2 into [`PathBuf`], row and col.
+///
+/// Does not validate if file.rs is a file or directory.
+fn split_path_row_col(s: &str) -> Option<(PathBuf, Position)> {
+ let mut s = s.rsplitn(3, ':');
+ let col: usize = s.next()?.parse().ok()?;
+ let row: usize = s.next()?.parse().ok()?;
+ let path = s.next()?.into();
+ let pos = Position::new(row.saturating_sub(1), col.saturating_sub(1));
+ Some((path, pos))
+}
+
+/// Split file.rs:10 into [`PathBuf`] and row.
+///
+/// Does not validate if file.rs is a file or directory.
+fn split_path_row(s: &str) -> Option<(PathBuf, Position)> {
+ let (row, path) = s.rsplit_once(':')?;
+ let row: usize = row.parse().ok()?;
+ let path = path.into();
+ let pos = Position::new(row.saturating_sub(1), 0);
+ Some((path, pos))
+}