summaryrefslogtreecommitdiffstats
path: root/atuin-client
diff options
context:
space:
mode:
authorEllie Huxtable <e@elm.sh>2021-04-26 11:50:31 +0100
committerEllie Huxtable <e@elm.sh>2021-04-26 11:57:30 +0100
commit7b5c3d543d198a18884c990d540f5debc8a4d8d5 (patch)
treeffc6b9121f1b1299f1b30a26322e1988683c06c7 /atuin-client
parent4f16e8411e24891b140690798c47747f5c9bb91e (diff)
Support bash, resolves #3
Diffstat (limited to 'atuin-client')
-rw-r--r--atuin-client/src/import/bash.rs79
-rw-r--r--atuin-client/src/import/mod.rs15
-rw-r--r--atuin-client/src/import/zsh.rs (renamed from atuin-client/src/import.rs)69
-rw-r--r--atuin-client/src/sync.rs2
4 files changed, 126 insertions, 39 deletions
diff --git a/atuin-client/src/import/bash.rs b/atuin-client/src/import/bash.rs
new file mode 100644
index 00000000..d5fbef46
--- /dev/null
+++ b/atuin-client/src/import/bash.rs
@@ -0,0 +1,79 @@
+use std::io::{BufRead, BufReader};
+use std::{fs::File, path::Path};
+
+use eyre::{eyre, Result};
+
+use super::count_lines;
+use crate::history::History;
+
+#[derive(Debug)]
+pub struct Bash {
+ file: BufReader<File>,
+
+ pub loc: u64,
+ pub counter: i64,
+}
+
+impl Bash {
+ pub fn new(path: impl AsRef<Path>) -> Result<Self> {
+ let file = File::open(path)?;
+ let mut buf = BufReader::new(file);
+ let loc = count_lines(&mut buf)?;
+
+ Ok(Self {
+ file: buf,
+ loc: loc as u64,
+ counter: 0,
+ })
+ }
+
+ fn read_line(&mut self) -> Option<Result<String>> {
+ let mut line = String::new();
+
+ match self.file.read_line(&mut line) {
+ Ok(0) => None,
+ Ok(_) => Some(Ok(line)),
+ Err(e) => Some(Err(eyre!("failed to read line: {}", e))), // we can skip past things like invalid utf8
+ }
+ }
+}
+
+impl Iterator for Bash {
+ type Item = Result<History>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let line = self.read_line()?;
+
+ if let Err(e) = line {
+ return Some(Err(e)); // :(
+ }
+
+ let mut line = line.unwrap();
+
+ while line.ends_with("\\\n") {
+ let next_line = self.read_line()?;
+
+ if next_line.is_err() {
+ break;
+ }
+
+ line.push_str(next_line.unwrap().as_str());
+ }
+
+ let time = chrono::Utc::now();
+ let offset = chrono::Duration::seconds(self.counter);
+ let time = time - offset;
+
+ self.counter += 1;
+
+ Some(Ok(History::new(
+ time,
+ line.trim_end().to_string(),
+ String::from("unknown"),
+ -1,
+ -1,
+ None,
+ None,
+ )))
+ }
+}
diff --git a/atuin-client/src/import/mod.rs b/atuin-client/src/import/mod.rs
new file mode 100644
index 00000000..3f8ea355
--- /dev/null
+++ b/atuin-client/src/import/mod.rs
@@ -0,0 +1,15 @@
+use std::fs::File;
+use std::io::{BufRead, BufReader, Seek, SeekFrom};
+
+use eyre::Result;
+
+pub mod bash;
+pub mod zsh;
+
+// this could probably be sped up
+fn count_lines(buf: &mut BufReader<File>) -> Result<usize> {
+ let lines = buf.lines().count();
+ buf.seek(SeekFrom::Start(0))?;
+
+ Ok(lines)
+}
diff --git a/atuin-client/src/import.rs b/atuin-client/src/import/zsh.rs
index 3b0b2a69..46e9af63 100644
--- a/atuin-client/src/import.rs
+++ b/atuin-client/src/import/zsh.rs
@@ -1,7 +1,7 @@
// import old shell history!
// automatically hoover up all that we can find
-use std::io::{BufRead, BufReader, Seek, SeekFrom};
+use std::io::{BufRead, BufReader};
use std::{fs::File, path::Path};
use chrono::prelude::*;
@@ -9,7 +9,8 @@ use chrono::Utc;
use eyre::{eyre, Result};
use itertools::Itertools;
-use super::history::History;
+use super::count_lines;
+use crate::history::History;
#[derive(Debug)]
pub struct Zsh {
@@ -19,14 +20,6 @@ pub struct Zsh {
pub counter: i64,
}
-// this could probably be sped up
-fn count_lines(buf: &mut BufReader<File>) -> Result<usize> {
- let lines = buf.lines().count();
- buf.seek(SeekFrom::Start(0))?;
-
- Ok(lines)
-}
-
impl Zsh {
pub fn new(path: impl AsRef<Path>) -> Result<Self> {
let file = File::open(path)?;
@@ -39,36 +32,7 @@ impl Zsh {
counter: 0,
})
}
-}
-
-fn parse_extended(line: &str, counter: i64) -> History {
- let line = line.replacen(": ", "", 2);
- let (time, duration) = line.splitn(2, ':').collect_tuple().unwrap();
- let (duration, command) = duration.splitn(2, ';').collect_tuple().unwrap();
-
- let time = time
- .parse::<i64>()
- .unwrap_or_else(|_| chrono::Utc::now().timestamp());
-
- let offset = chrono::Duration::milliseconds(counter);
- let time = Utc.timestamp(time, 0);
- let time = time + offset;
-
- let duration = duration.parse::<i64>().map_or(-1, |t| t * 1_000_000_000);
- // use nanos, because why the hell not? we won't display them.
- History::new(
- time,
- command.trim_end().to_string(),
- String::from("unknown"),
- 0, // assume 0, we have no way of knowing :(
- duration,
- None,
- None,
- )
-}
-
-impl Zsh {
fn read_line(&mut self) -> Option<Result<String>> {
let mut line = String::new();
@@ -140,6 +104,33 @@ impl Iterator for Zsh {
}
}
+fn parse_extended(line: &str, counter: i64) -> History {
+ let line = line.replacen(": ", "", 2);
+ let (time, duration) = line.splitn(2, ':').collect_tuple().unwrap();
+ let (duration, command) = duration.splitn(2, ';').collect_tuple().unwrap();
+
+ let time = time
+ .parse::<i64>()
+ .unwrap_or_else(|_| chrono::Utc::now().timestamp());
+
+ let offset = chrono::Duration::milliseconds(counter);
+ let time = Utc.timestamp(time, 0);
+ let time = time + offset;
+
+ let duration = duration.parse::<i64>().map_or(-1, |t| t * 1_000_000_000);
+
+ // use nanos, because why the hell not? we won't display them.
+ History::new(
+ time,
+ command.trim_end().to_string(),
+ String::from("unknown"),
+ 0, // assume 0, we have no way of knowing :(
+ duration,
+ None,
+ None,
+ )
+}
+
#[cfg(test)]
mod test {
use chrono::prelude::*;
diff --git a/atuin-client/src/sync.rs b/atuin-client/src/sync.rs
index 813c2ed4..5c6405df 100644
--- a/atuin-client/src/sync.rs
+++ b/atuin-client/src/sync.rs
@@ -123,6 +123,8 @@ async fn sync_upload(
client.post_history(&buffer).await?;
cursor = buffer.last().unwrap().timestamp;
remote_count = client.count().await?;
+
+ debug!("upload cursor: {:?}", cursor);
}
Ok(())