There's no need to call zle reset-prompt in precmd since the prompt has
yet to be rendered. This commit separates the widget functionality
(reset prompt) and restoring the prompt symbol.
The logic here is that if we unset ZSH_THEME during Pure init, we guard
against this scenario:
```
ZSH_THEME=sometheme
prompt pure
source $ZSH/oh-my-zsh.zsh
```
Also, by unsetting ZSH_THEME we can detect the following scenario:
```
prompt pure
ZSH_THEME=othertheme
source $ZSH/oh-my-zsh.zsh
```
And in this case, we show a warning, because there's no telling what
that OMZ theme might have done (precmd hooks, etc).
* Prevent hostname from showing up in local X sessions
This change prevents the hostname from showing up when a terminal is
opened inside a local X session (displayed as (:1)).
Fixes a regression introduced in #393.
* Implement a more robust remote connection detection (who)
First, we switch from `who am i` to `who -m` because this is the POSIX
way and macOS supports it as well.
Second, if the above fails, we fall back to using just `who` and grep
the line that represents our TTY. This works e.g. with busybox systems.
Finally, we use (extremely) simplified regular expressions for detecting
IPv4, IPv6 and hostname. This is a best-effort attempt at detecting the
remote connections when SSH_CONNECTION is not set.
* Inherit SSH connection detection inside tmux or other subshells
* Store match and use upper case export for consistency
This will also help with debugging if a user ever runs into a problem
where the user/host is shown when it should not be:
# typeset -p PROMPT_PURE_SSH_CONNECTION
export PROMPT_PURE_SSH_CONNECTION='(::1)'
* Improve the debug prompt (PS4)
Add colors, to highlight the current function and de-empasize line numbers.
Add an extra line number (`%I`) which represents the line number in the file
where the code resides (by default, only the function line number is shown,
making it hard(er) to find the relevant code).
Repeat the + character to indicate the current execution depth, e.g. when a
function calls another, the depth is increased. This allows you to quickly see
which function invoked which.
* Add filename to debug prompt
Add filename (without path) to the debug prompt, when applicable and makes sure
to avoid displaying duplicate information. Say, when a file is being parsed,
both %N and %x contain the same value (file path). In this case, we only show
one value.
There is a slight cost to doing the extra processing when testing in
iTerm (unscientific benchmark):
zsh -x 0.30s user 0.14s system 57% cpu 0.754 total
vs
zsh -x 0.49s user 0.16s system 65% cpu 0.988 total
I think this is within an acceptable range.
We set the shell into MONITOR mode to prevent password prompts from
hijacking the TTY. If the command is suspended we know it's trying
something not nice. So we kill it.
This seems a bit crazy, but at least it does not seem to affect
performance (relatively). I also have found no other way to work around
these issues.
Although we already set:
```
export GIT_SSH_COMMAND="${GIT_SSH_COMMAND:-"ssh"} -o BatchMode=yes"
```
It is not sufficient. For example, when a SSH configuration entry
contains the ProxyJump option it will usually invoke a new instance of
ssh which does not obey the BatchMode option we specified.
I tried both zsh 4.3.17 and 5.0.2 to be sure it doesn't break easily...
Fixes#373.
Previously, `setopt xtrace` would produce terminal bell rings (by \a)
whenever the title was set because of debug output between print
statements. As a result, the title was not set and the terminal bell
rang.
This change also utilizes the improved ssh connection detection to
provide hostname in title when changing user on remote machines.
It seems that adding the initial newline in `$PROMPT` allows ZLE to
erase the entile line where the newline began. This is problematic when
command output does not end with its own newline. A subsequent terminal
resize or prompt update that triggers a prompt redraw will then erase
the line.
To fix this, we separate the newline from the prompt by calling print
manually during precmd.
Previously, Pure tried to keep any potential prefixes the user might
have added to the PROMPT (before preprompt). This fix no longer allows
such prefixes as doing so would be hackish, and likely a recipe for
other unforseen behavior.
NOTE: Because the newline is printed by the Pure precmd hook, it's
possible that another precmd hook is run afterwards, and if that hook
outputs any text, the newline will appear in the wrong place. A possible
solution would be to delay adding the hook or at a later point sort the
hooks so that Pure is last.
Fixes#390, #376.
This change allows us to detect SSH connections even when the
`$SSH_CONNECTION` environment variable is gone. This can happen when a
user changes to another user (`su`, `sudo`) or the environment is
otherwise reset.
By checking the output of `who am i` for a parenthesis at the end, we
assume that said parenthesis must contain either an IPv4 or IPv6
address, indicating that this is a remote session.
The reliablity of this assumption has not been analyzed to a great
degree, there could be false positives, or systems that do not format
the output in this way.
Fixes#382.
The previous implementation did not disable SSH password prompts when
`GIT_SSH_COMMAND` has been set. This allowed the zsh-async worker to
"break" due to an interactive program capturing keystrokes, which were
actually output from the worker.
Fixes#373.
When `VIRTUAL_ENV_DISABLE_PROMPT` is set (to true) by the user, Pure
will not display the virtualenv in the prompt. Setting this manually
likely means the user does not care.
The user can, at any point, run `export VIRTUAL_ENV_DISABLE_PROMPT=1`
and the virtualenv will disappear. Likewise,
`unset VIRTUAL_ENV_DISABLE_PROMPT` will bring it back.
Closes#350.
A big thanks to classner and pfrybar for their efforts and reference
implementations, inspiring this one.
* Update zsh-async to 1.6.0 for buffer status indicator
* Prevent multiple prompt resets in one execution cycle
The prompt ends up in a weird state when `zle reset-prompt` is called
multiple times during one execution cycle. This can happen when multiple
async tasks finish at nearly the same time. What happened here is that
`async_process_results` called `prompt_pure_async_callback` multiple
times during it's execution. In turn, `prompt_pure_async_callback` did
multiple calls to `zle reset-prompt`. My theory is that ZLE ends up in a
weird state that is reset after all the current code has completed
executing.
This behavior is observable when the prompt "moves upwards" and erases
previous lines in the terminal.
Fixes#356.
In prompt_pure_preexec we perform a match using both the (#b) glob flag
(match, mbegin, mend) and the (#m) flag (MATCH, MBEGIN, MEND). We must
mark these variables local to avoid triggering the WARN_CREATE_GLOBAL
option.
This commit also adds MBEGIN and MEND to places where only MATCH was
marked local.
References: https://github.com/sindresorhus/pure/issues/345
This change will prevent `setopt warn_create_global` from showing errors
and give the reader a better understanding of how the variable is used
(global or local scope).
The preprompt render guard logic of `prompt_pure_cmd_timestamp` was also
removed because this can no longer happen. If a command is running, ZLE
will not be active and `zle reset-prompt` will do nothing.
Closes#345.
Oh-my-zsh overrides PS1 even when no theme is set, this commit adds a
note to the readme about the need to activate Pure *after* oh-my-zsh.
Closes#315.