summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKoichi Murase <myoga.murase@gmail.com>2024-04-17 21:56:07 +0900
committerGitHub <noreply@github.com>2024-04-17 13:56:07 +0100
commit4f26963c9968400e12251be8cf671a5d40680451 (patch)
treeab7b0b25c7d070b5720243ef7e65a3a6ed51afb1
parent19f70cdc918769e0485b0e4aba4069327e96dc3b (diff)
feat(doctor): detect active preexec framework (#1955)
* feat(doctor): check active preexec framework To check if "blesh" or "bash-preexec" is loaded and active in the current Bash session where `atuin doctor` is called, we make the Atuin integration script for Bash to set the environment variable `ATUIN_PREEXEC_BACKEND` and store a string when it detects "blesh" or "bash-preexec". To check whether the obtained ATUIN_PREEXEC_BACKEND is set by the current session, we record SHLVL in ATUIN_PREEXEC_BACKEND and check if it matches SHLVL of the current process. * feat(doctor): detect the case where Atuin is initialized before blesh
-rw-r--r--atuin/src/command/client/doctor.rs48
-rw-r--r--atuin/src/shell/atuin.bash17
2 files changed, 61 insertions, 4 deletions
diff --git a/atuin/src/command/client/doctor.rs b/atuin/src/command/client/doctor.rs
index fa76df76..48659ed1 100644
--- a/atuin/src/command/client/doctor.rs
+++ b/atuin/src/command/client/doctor.rs
@@ -19,6 +19,9 @@ struct ShellInfo {
// Detect some shell plugins that the user has installed.
// I'm just going to start with preexec/blesh
pub plugins: Vec<String>,
+
+ // The preexec framework used in the current session, if Atuin is loaded.
+ pub preexec: Option<String>,
}
impl ShellInfo {
@@ -43,6 +46,31 @@ impl ShellInfo {
cmd.contains("ATUIN_DOCTOR_ENV_FOUND")
}
+ fn detect_preexec_framework(shell: &str) -> Option<String> {
+ if env::var("ATUIN_SESSION").ok().is_none() {
+ None
+ } else if shell.starts_with("bash") || shell == "sh" {
+ env::var("ATUIN_PREEXEC_BACKEND")
+ .ok()
+ .filter(|value| !value.is_empty())
+ .and_then(|atuin_preexec_backend| {
+ atuin_preexec_backend.rfind(':').and_then(|pos_colon| {
+ u32::from_str(&atuin_preexec_backend[..pos_colon])
+ .ok()
+ .is_some_and(|preexec_shlvl| {
+ env::var("SHLVL")
+ .ok()
+ .and_then(|shlvl| u32::from_str(&shlvl).ok())
+ .is_some_and(|shlvl| shlvl == preexec_shlvl)
+ })
+ .then(|| atuin_preexec_backend[pos_colon + 1..].to_string())
+ })
+ })
+ } else {
+ Some("built-in".to_string())
+ }
+ }
+
fn validate_plugin_blesh(
_shell: &str,
shell_process: &sysinfo::Process,
@@ -156,10 +184,13 @@ impl ShellInfo {
let default = Shell::default_shell().unwrap_or(Shell::Unknown).to_string();
+ let preexec = Self::detect_preexec_framework(name.as_str());
+
Self {
name,
default,
plugins,
+ preexec,
}
}
}
@@ -272,6 +303,7 @@ fn checks(info: &DoctorDump) {
//
let zfs_error = "[Filesystem] ZFS is known to have some issues with SQLite. Atuin uses SQLite heavily. If you are having poor performance, there are some workarounds here: https://github.com/atuinsh/atuin/issues/952".bold().red();
let bash_plugin_error = "[Shell] If you are using Bash, Atuin requires that either bash-preexec or ble.sh be installed. An older ble.sh may not be detected. so ignore this if you have it set up! Read more here: https://docs.atuin.sh/guide/installation/#bash".bold().red();
+ let blesh_loading_order_error = "[Shell] Atuin seems to be loaded before ble.sh is sourced. In .bashrc, make sure to initialize Atuin after sourcing ble.sh.".bold().red();
// ZFS: https://github.com/atuinsh/atuin/issues/952
if info.system.disks.iter().any(|d| d.filesystem == "zfs") {
@@ -279,14 +311,22 @@ fn checks(info: &DoctorDump) {
}
// Shell
- if info.shell.name == "bash"
- && !info
+ if info.shell.name == "bash" {
+ if !info
.shell
.plugins
.iter()
.any(|p| p == "blesh" || p == "bash-preexec")
- {
- println!("{bash_plugin_error}");
+ {
+ println!("{bash_plugin_error}");
+ }
+
+ if info.shell.plugins.iter().any(|plugin| plugin == "atuin")
+ && info.shell.plugins.iter().any(|plugin| plugin == "blesh")
+ && info.shell.preexec.as_ref().is_some_and(|val| val == "none")
+ {
+ println!("{blesh_loading_order_error}");
+ }
}
}
diff --git a/atuin/src/shell/atuin.bash b/atuin/src/shell/atuin.bash
index 885729b0..8eda0a6f 100644
--- a/atuin/src/shell/atuin.bash
+++ b/atuin/src/shell/atuin.bash
@@ -17,6 +17,19 @@ ATUIN_STTY=$(stty -g)
export ATUIN_SESSION
ATUIN_HISTORY_ID=""
+export ATUIN_PREEXEC_BACKEND=$SHLVL:none
+__atuin_update_preexec_backend() {
+ if [[ ${BLE_ATTACHED-} ]]; then
+ ATUIN_PREEXEC_BACKEND=$SHLVL:blesh-${BLE_VERSION-}
+ elif [[ ${bash_preexec_imported-} ]]; then
+ ATUIN_PREEXEC_BACKEND=$SHLVL:bash-preexec
+ elif [[ ${__bp_imported-} ]]; then
+ ATUIN_PREEXEC_BACKEND="$SHLVL:bash-preexec (old)"
+ else
+ ATUIN_PREEXEC_BACKEND=$SHLVL:unknown
+ fi
+}
+
__atuin_preexec() {
# Workaround for old versions of bash-preexec
if [[ ! ${BLE_ATTACHED-} ]]; then
@@ -33,6 +46,10 @@ __atuin_preexec() {
fi
fi
+ # Note: We update ATUIN_PREEXEC_BACKEND on every preexec because blesh's
+ # attaching state can dynamically change.
+ __atuin_update_preexec_backend
+
local id
id=$(atuin history start -- "$1")
export ATUIN_HISTORY_ID=$id