aboutsummaryrefslogtreecommitdiffstats
path: root/atuin-client/src/import/nu.rs
diff options
context:
space:
mode:
authorSteven Xu <stevenxxiu@users.noreply.github.com>2023-03-27 01:44:06 +1100
committerGitHub <noreply@github.com>2023-03-26 15:44:06 +0100
commita7cb21a51b393b436c0ca7e09c892ebb3c597ad0 (patch)
treed55d1ad07d5d01ccac6f5100bf4d131da748537c /atuin-client/src/import/nu.rs
parentAdd musl build (#809) (diff)
downloadatuin-a7cb21a51b393b436c0ca7e09c892ebb3c597ad0.zip
feat: add *Nushell* support (#788)
* feat: add *Nushell* support * refactor: use `sh` to swap `STDOUT` and `STDERR` instead of using a temporary file * feat: include both keybindings, with the current REPL buffer passed to *Atuin*'s * feat: don't record commands run by keybindings
Diffstat (limited to 'atuin-client/src/import/nu.rs')
-rw-r--r--atuin-client/src/import/nu.rs76
1 files changed, 76 insertions, 0 deletions
diff --git a/atuin-client/src/import/nu.rs b/atuin-client/src/import/nu.rs
new file mode 100644
index 00000000..0f107604
--- /dev/null
+++ b/atuin-client/src/import/nu.rs
@@ -0,0 +1,76 @@
+// import old shell history!
+// automatically hoover up all that we can find
+
+use std::{fs::File, io::Read, path::PathBuf};
+
+use async_trait::async_trait;
+use directories::BaseDirs;
+use eyre::{eyre, Result};
+
+use super::{unix_byte_lines, Importer, Loader};
+use crate::history::History;
+
+#[derive(Debug)]
+pub struct Nu {
+ bytes: Vec<u8>,
+}
+
+fn get_histpath() -> Result<PathBuf> {
+ let base = BaseDirs::new().ok_or_else(|| eyre!("could not determine data directory"))?;
+ let config_dir = base.config_dir().join("nushell");
+
+ let histpath = config_dir.join("history.txt");
+ if histpath.exists() {
+ Ok(histpath)
+ } else {
+ Err(eyre!("Could not find history file."))
+ }
+}
+
+#[async_trait]
+impl Importer for Nu {
+ const NAME: &'static str = "nu";
+
+ async fn new() -> Result<Self> {
+ let mut bytes = Vec::new();
+ let path = get_histpath()?;
+ let mut f = File::open(path)?;
+ f.read_to_end(&mut bytes)?;
+ Ok(Self { bytes })
+ }
+
+ async fn entries(&mut self) -> Result<usize> {
+ Ok(super::count_lines(&self.bytes))
+ }
+
+ async fn load(self, h: &mut impl Loader) -> Result<()> {
+ let now = chrono::Utc::now();
+
+ let mut counter = 0;
+ for b in unix_byte_lines(&self.bytes) {
+ let s = match std::str::from_utf8(b) {
+ Ok(s) => s,
+ Err(_) => continue, // we can skip past things like invalid utf8
+ };
+
+ let cmd: String = s.replace("<\\n>", "\n");
+
+ let offset = chrono::Duration::nanoseconds(counter);
+ counter += 1;
+
+ h.push(History::new(
+ now - offset, // preserve ordering
+ cmd,
+ String::from("unknown"),
+ -1,
+ -1,
+ None,
+ None,
+ None,
+ ))
+ .await?;
+ }
+
+ Ok(())
+ }
+}