chris-marsh / pureline

A Pure Bash Powerline PS1 Command Prompt
MIT License
501 stars 94 forks source link

duration_segment : using PS0 instead of 'trap DEBUG' #78

Open CyrilOtheninGirard opened 2 years ago

CyrilOtheninGirard commented 2 years ago

Both pureline 'duration_segment' and vscode 'shell integration' install a DEBUG trap to enhance the shell experience But both work by sourcing a script, and by default the DEBUG trap is not inherited in that case.

Solution 1 (rejected)

We could tell the user to add those lines in its .bashrc :

if [[ $(trap -p DEBUG) =~ ^trap ]]; then
    set -o functrace # same as 'set -T'
fi

... but this may have side-effects since it does MUCH MORE than what we wants :

set -o functrace
set -T
       If set, any traps on DEBUG and RETURN are inherited by shell functions,
       command substitutions, and commands executed in a subshell environment.
       The DEBUG and RETURN traps are normally not inherited in such cases.

Thus this solution is rejected.

Solution 2 (adopted)

In Bash 4+, the value of PS0 is expanded and displayed by interactive shells after reading a command and before the command is executed. PS0 is not evaluated for empty commands, which leaves a blank line.

We can use "Arithmetic expansion" to run __timer_start=$(timer_now) inside PS0 :

Thus the solution is to replace the DEBUG trap with this line:

PS0+='${0:0:$((__timer_start=$(timer_now),0))}'
CyrilOtheninGirard commented 2 years ago

Example : using pureline inside a vscode terminal where 'shell integration' is enabled.

Before (using the DEBUG trap) :

pureline in vscode - duration_segment - before fix

After (using PS0) :

pureline in vscode - duration_segment - after fix

Note: PS0 is not evaluated for empty commands, which leaves a blank line.

CyrilOtheninGirard commented 2 years ago

I solved conflicts with the base branch