rupa / z

z - jump around
Do What The F*ck You Want To Public License
16.37k stars 1.17k forks source link

Shell prompt lag in macOS #318

Open apas opened 2 years ago

apas commented 2 years ago

Longtime user and fan of z.sh. After many attempts to no avail at debugging the following, I'm opening this issue for discussion.

I'm running two machines, a macOS (local) and an Ubuntu (remote,) with the same dotfiles and shell configuration. Both are running the same version of bash (5.1.16(1).) Both shells are interactive login shells. And yet, when z.sh is sourced, the macOS shell prompt experiences a short but highly noticeable lag on each Return press, while the Ubuntu prompt is rendered instantly.

I was wondering if anyone else is experiencing the same issue (or similar) and how to fix — if possible.

Shell environment settings: (also available in my repo)

export PROMPT_COMMAND="history -a"
# other lines...
# point to and source z in order to track and build dir list
. $HOME/.bin/z.sh

As such, the PROMPT_COMMAND reads: history -a (_z --add "$(command pwd -P 2>/dev/null)" 2>/dev/null &);

$HOME/.bin/z.sh reflects the latest version from the master brach.

This has been also tested on a fresh macOS virtual machine with the same results.

apas commented 2 years ago

Kind bump. Thanks!

Lockszmith-GH commented 2 years ago

have you tried adding ; after history -a ?

as in:

export PROMPT_COMMAND="history -a ; "
# other lines...
# point to and source z in order to track and build dir list
. $HOME/.bin/z.sh
apas commented 2 years ago

Thanks, @Lockszmith-GH. I've just now -- no noticeable improvement.

$ echo $PROMPT_COMMAND
history -a; (_z --add "$(command pwd -P 2>/dev/null)" 2>/dev/null &);
Lockszmith-GH commented 2 years ago

Z stores it's history in a ~/.z file. How large is it in macOS compared to the Linux one?

One way I use to debug my .bashrc is to run it like this:

bash -xv ~/.bashrc

it will output every line before evaluation (-v) and after (-x) it executes. This might help identify where the stalling is happening.

If it's opaque and in the z source, try running the same command calling z that stalls the same way, and that may help identify the cause.

apas commented 2 years ago

Thanks for the reply.

macOS:

-rw-r--r--  2.1K Oct 26 09:45 .z

Ubuntu:

-rw-rw-r--  1.1K Nov  4 14:13 .z

If it's opaque and in the z source, try running the same command calling z that stalls the same way, and that may help identify the cause.

I'm not sure what you mean here. Here's an excerpt from -xv ~/.shell/utils.sh:

# point to and source z in order to track and build dir list
. $HOME/.bin/z.sh
+ . /Users/apas/.bin/z.sh
.
. 
. the entire z.sh script
. 
. 
++ type compctl
++ type complete
++ complete -o filenames -C '_z --complete "$COMP_LINE"' z
++ '[' '' ']'
++ grep '_z --add'
++ PROMPT_COMMAND='history -a;
(_z --add "$(command pwd -P 2>/dev/null)" 2>/dev/null &);'
Lockszmith-GH commented 2 years ago

OK, so if .bashrc runs properly (no lag), but each prompt rendering is slow - the issue isn't with .bashrc. I'm assuming that when you have only history -a; in PROMPT_COMMAND - it returns instantaneous, and it's only the _z function call that lags.

What you need to 'look into' is _z, the way to do that is:

  1. Clear the PROMPT_COMMAND - so you'll be sure it's the source.
  2. Run each of the command, and see which is the one causing the most delay:
    • history -a
    • command pwd -P 2>/dev/null
      • If this is slow you can use the same exact binary path instead of allowing command to dynamically resolve the location of pwd binary everytime:
        PWD_PATH="$(type -fP pwd)"
    • _z --add "$(command pwd -P 2>/dev/null)" 2>/dev/null &);
      • Try this without the & in the end - this runs the command in a forked subshell job. See if without & it returns faster.
      • Try replacing the command pwd... with $PWD_PATH 2>/dev/null after defining the variable as mentioned above.
      • Remove the 2>/dev/null from the command line and see if there are any errors.
  3. _z is still the cause of the slow-down, run the above command with set -x before it; and set +x after it, like this:
    set -x; _z --add "$(command pwd -P 2>/dev/null)" 2>/dev/null &); set +x;

    This switches on the printout of each command, should also affect the internals of _z. See if you can find the point where it slows down.

Hope all of this actually helps.