aboutsummaryrefslogtreecommitdiffstats
path: root/atuin-common
diff options
context:
space:
mode:
Diffstat (limited to 'atuin-common')
-rw-r--r--atuin-common/Cargo.toml2
-rw-r--r--atuin-common/src/lib.rs1
-rw-r--r--atuin-common/src/shell.rs66
3 files changed, 69 insertions, 0 deletions
diff --git a/atuin-common/Cargo.toml b/atuin-common/Cargo.toml
index 847cea96..85e41ef6 100644
--- a/atuin-common/Cargo.toml
+++ b/atuin-common/Cargo.toml
@@ -21,6 +21,8 @@ typed-builder = { workspace = true }
eyre = { workspace = true }
sqlx = { workspace = true }
semver = { workspace = true }
+thiserror = { workspace = true }
+sysinfo = "0.30.7"
lazy_static = "1.4.0"
diff --git a/atuin-common/src/lib.rs b/atuin-common/src/lib.rs
index d4513ee0..2d848f6f 100644
--- a/atuin-common/src/lib.rs
+++ b/atuin-common/src/lib.rs
@@ -54,4 +54,5 @@ macro_rules! new_uuid {
pub mod api;
pub mod record;
+pub mod shell;
pub mod utils;
diff --git a/atuin-common/src/shell.rs b/atuin-common/src/shell.rs
new file mode 100644
index 00000000..2c0f3534
--- /dev/null
+++ b/atuin-common/src/shell.rs
@@ -0,0 +1,66 @@
+use sysinfo::{get_current_pid, Process, System};
+use thiserror::Error;
+
+pub enum Shell {
+ Sh,
+ Bash,
+ Fish,
+ Zsh,
+ Xonsh,
+ Nu,
+
+ Unknown,
+}
+
+#[derive(Debug, Error)]
+pub enum ShellError {
+ #[error("shell not supported")]
+ NotSupported,
+
+ #[error("failed to execute shell command: {0}")]
+ ExecError(String),
+}
+
+pub fn shell() -> Shell {
+ let name = shell_name(None);
+
+ match name.as_str() {
+ "bash" => Shell::Bash,
+ "fish" => Shell::Fish,
+ "zsh" => Shell::Zsh,
+ "xonsh" => Shell::Xonsh,
+ "nu" => Shell::Nu,
+ "sh" => Shell::Sh,
+
+ _ => Shell::Unknown,
+ }
+}
+
+impl Shell {
+ /// Returns true if the shell is posix-like
+ /// Note that while fish is not posix compliant, it behaves well enough for our current
+ /// featureset that this does not matter.
+ pub fn is_posixish(&self) -> bool {
+ matches!(self, Shell::Bash | Shell::Fish | Shell::Zsh)
+ }
+}
+
+pub fn shell_name(parent: Option<&Process>) -> String {
+ let sys = System::new_all();
+
+ let parent = if let Some(parent) = parent {
+ parent
+ } else {
+ let process = sys
+ .process(get_current_pid().expect("Failed to get current PID"))
+ .expect("Process with current pid does not exist");
+
+ sys.process(process.parent().expect("Atuin running with no parent!"))
+ .expect("Process with parent pid does not exist")
+ };
+
+ let shell = parent.name().trim().to_lowercase();
+ let shell = shell.strip_prefix('-').unwrap_or(&shell);
+
+ shell.to_string()
+}