diff options
author | Koichi Murase <myoga.murase@gmail.com> | 2024-04-17 21:56:07 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-17 13:56:07 +0100 |
commit | 4f26963c9968400e12251be8cf671a5d40680451 (patch) | |
tree | ab7b0b25c7d070b5720243ef7e65a3a6ed51afb1 | |
parent | 19f70cdc918769e0485b0e4aba4069327e96dc3b (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.rs | 48 | ||||
-rw-r--r-- | atuin/src/shell/atuin.bash | 17 |
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 |