Skip to content

Commit

Permalink
Add raw string passing to fix title issues
Browse files Browse the repository at this point in the history
The problem is simple enough: the extra backslashes or percents that
__lp_escape() adds show up in the title, as the title is changed in the
previous commit to no longer be printed as part of PS1. The fix is not
so simple.

This patch adds "raw" copy of the data strings for username, hostname,
and current path with no color or shell character escaping. This is
designed for putting into the terminal title, but it could also be used
for comparisons. lp_path_format() already had a no formatting return var
in lp_path, but now it is not shell escaped.

The title is changed from duplicating the prompt to instead showing just
the core bits in the central brackets: username, hostname, current path,
followed by the prompt mark. As well as the user prefix, postfix, and
MARK_PREFIX. This is a change from the long standing default, but it is
customizable both by themes and users, and I have long seen complaints
of the current title layout being less than helpful.

There is one small issue though: to prevent LP_PS1_PREFIX,
LP_PS1_POSTFIX, and LP_MARK_PREFIX that have color from messing up the
title, the whole title string is still passed into lp_formatted_title()
to strip color out. This is less than ideal, but faster than treating
those 3 variables by themselves.
  • Loading branch information
Rycieos committed Apr 8, 2021
1 parent 0c23a33 commit a23af79
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 47 deletions.
26 changes: 19 additions & 7 deletions docs/functions/data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -249,19 +249,23 @@ OS

.. versionadded:: 2.0

.. function:: _lp_hostname() -> var:lp_hostname
.. function:: _lp_hostname() -> var:lp_hostname, var:lp_hostname_raw

Returns ``true`` if a hostname should be displayed. Returns ``1`` if the
connection type is local and :attr:`LP_HOSTNAME_ALWAYS` is not ``1``.

Returns the hostname string.
Returns the hostname string in *lp_hostname*.

Returns the hostname string not passed through :func:`__lp_escape` in
*lp_hostname_raw*.

Can be disabled by :attr:`LP_HOSTNAME_ALWAYS` set to ``-1``.

.. versionadded:: 2.0

.. versionchanged:: 2.1
Returns the actual hostname instead of a shell prompt escape code.
Added *lp_hostname_raw* return value.
No longer sets :attr:`LP_HOST_SYMBOL` to the same return string.

.. function:: _lp_sudo_active()
Expand All @@ -284,19 +288,23 @@ OS

.. versionadded:: 2.0

.. function:: _lp_username() -> var:lp_username
.. function:: _lp_username() -> var:lp_username, var:lp_username_raw

Returns ``true`` if a username should be displayed. Returns ``1`` if the
user is the login user and :attr:`LP_USER_ALWAYS` is not ``1``.

Returns the current user ID.
Returns the current user ID in *lp_username*.

Returns the current user ID not passed through :func:`__lp_escape` in
*lp_username_raw*.

Can be disabled by :attr:`LP_USER_ALWAYS` set to ``-1``.

.. versionadded:: 2.0

.. versionchanged:: 2.1
Returns the actual username instead of a shell prompt escape code.
Added *lp_username_raw* return value.

Path
----
Expand All @@ -307,9 +315,10 @@ Path
[separator_format]) -> var:lp_path, var:lp_path_format

Returns a shortened and formatted string indicating the current working
directory path. *lp_path* contains the path without any formatting or custom
separators, intended for use in the terminal title. *lp_path_format* contains
the complete formatted path, to be inserted into the prompt.
directory path. *lp_path* contains the path without any formatting, custom
separators, or shell escapes, intended for use in the terminal title.
*lp_path_format* contains the complete formatted path, to be inserted into
the prompt.

The behavior of the shortening is controlled by
:attr:`LP_ENABLE_SHORTEN_PATH`, :attr:`LP_PATH_METHOD`,
Expand Down Expand Up @@ -339,6 +348,9 @@ Path

.. versionadded:: 2.0

.. versionchanged:: 2.1
Changed *lp_path* to no longer contain shell escapes.

Runtime
-------

Expand Down
57 changes: 26 additions & 31 deletions liquidprompt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ if test -n "${BASH_VERSION-}"; then

_LP_FIRST_INDEX=0
_LP_PERCENT='%' # must be escaped on zsh
_LP_BACKSLASH='\\' # must be escaped on bash

# Sed expression using extended regexp to match terminal
# escape sequences with their wrappers
Expand Down Expand Up @@ -68,12 +67,11 @@ elif test -n "${ZSH_VERSION-}" ; then

_LP_FIRST_INDEX=1
_LP_PERCENT='%%'
_LP_BACKSLASH="\\"

_LP_CLEAN_ESC='%\{([^%]+|%[^}])*%\}'

__lp_escape() {
ret="${1//\%/$_LP_PERCENT}"
ret="${1//\%/%%}"
}
else
echo "liquidprompt: shell not supported" >&2
Expand Down Expand Up @@ -502,8 +500,7 @@ lp_activate() {
if _lp_multiplexer; then
(( LP_ENABLE_TITLE = LP_ENABLE_TITLE && LP_ENABLE_SCREEN_TITLE ))
LP_TITLE_OPEN=$'\Ek'
# "\e\" but on bash \ must be escaped
LP_TITLE_CLOSE=$'\E'"$_LP_BACKSLASH"
LP_TITLE_CLOSE=$'\E\\'
else
LP_TITLE_OPEN=$'\E]0;'
LP_TITLE_CLOSE=$'\a'
Expand Down Expand Up @@ -891,18 +888,18 @@ _lp_path_format() {

if [[ $path_length == 1 || $LP_PATH_METHOD == "truncate_to_last_dir" ]]; then
if [[ $path_length > 1 ]]; then
__lp_escape "${display_path##*/}"
lp_path=$ret
lp_path=${display_path##*/}
else
# only root or home to show
__lp_escape "$display_path"
lp_path=$ret
lp_path=$display_path
fi

__lp_escape "$lp_path"

if [[ $display_path == $vcs_root_directory ]]; then
lp_path_format="${vcs_root_format}${lp_path}"
lp_path_format="${vcs_root_format}${ret}"
else
lp_path_format="${last_directory_format}${lp_path}"
lp_path_format="${last_directory_format}${ret}"
fi
return
else
Expand Down Expand Up @@ -943,23 +940,23 @@ _lp_path_format() {
if [[ $current_path == $vcs_root_directory ]]; then
__lp_end_path_left_shortening
# No shortening
lp_path+=$current_directory
__lp_escape "$current_directory"
lp_path+=$ret
lp_path_format+="${vcs_root_format}${ret}"
elif [[ -z $path_to_proccess ]]; then
__lp_end_path_left_shortening
# Last directory
lp_path+=$current_directory
__lp_escape "$current_directory"
lp_path+=$ret
lp_path_format+="${last_directory_format}${ret}"
elif (( LP_ENABLE_SHORTEN_PATH && directory_count > LP_PATH_KEEP \
&& ( shortened_path_length > max_len || ( shortened_path_length >= max_len && is_shortening ) ) )); then

if [[ $LP_PATH_METHOD == "truncate_chars_to_unique_dir" ]] && \
__lp_get_unique_directory "$current_path"; then

lp_path+=$lp_unique_directory
__lp_escape "$lp_unique_directory"
lp_path+=$ret
lp_path_format+="${shortened_directory_format}${ret}"
shortened_path_length=$(( shortened_path_length - ${#current_directory} + ${#lp_unique_directory} ))
elif [[ $LP_PATH_METHOD == "truncate_chars_from_path_left" ]]; then
Expand Down Expand Up @@ -989,8 +986,8 @@ _lp_path_format() {
shortened_path_length=$(( shortened_path_length - needed_length ))

shortened_path="${LP_MARK_SHORTEN_PATH}${current_directory:$needed_length}"
lp_path+=$shortened_path
__lp_escape "$shortened_path"
lp_path+=$ret
lp_path_format+="${shortened_directory_format}${ret}"

is_shortening=0
Expand All @@ -999,29 +996,29 @@ _lp_path_format() {
(( ${#LP_MARK_SHORTEN_PATH} + LP_PATH_CHARACTER_KEEP < ${#current_directory} )); then

shortened_path="${current_directory:0:$LP_PATH_CHARACTER_KEEP}${LP_MARK_SHORTEN_PATH}"
lp_path+=$shortened_path
__lp_escape "$shortened_path"
lp_path+=$ret
lp_path_format+="${shortened_directory_format}${ret}"
shortened_path_length=$(( shortened_path_length - ${#current_directory} + ${#LP_MARK_SHORTEN_PATH} + LP_PATH_CHARACTER_KEEP ))
elif [[ $LP_PATH_METHOD == "truncate_chars_from_dir_middle" ]] && \
(( ${#LP_MARK_SHORTEN_PATH} + LP_PATH_CHARACTER_KEEP * 2 < ${#current_directory} )); then

shortened_path="${current_directory:0:$LP_PATH_CHARACTER_KEEP}${LP_MARK_SHORTEN_PATH}${current_directory: -$LP_PATH_CHARACTER_KEEP}"
lp_path+=$shortened_path
__lp_escape "$shortened_path"
lp_path+=$ret
lp_path_format+="${shortened_directory_format}${ret}"
shortened_path_length=$(( shortened_path_length - ${#current_directory} + ${#LP_MARK_SHORTEN_PATH} + LP_PATH_CHARACTER_KEEP * 2 ))
else
# Need to shorten, but no method matched, or the matched method
# did not make the string any shorter.
lp_path+=$current_directory
__lp_escape "$current_directory"
lp_path+=$ret
lp_path_format+="${path_format}${ret}"
fi
else
__lp_end_path_left_shortening
lp_path+=$current_directory
__lp_escape "$current_directory"
lp_path+=$ret
lp_path_format+="${path_format}${ret}"
fi

Expand Down Expand Up @@ -1206,22 +1203,20 @@ _lp_user() {
_lp_username() {
if (( LP_USER_ALWAYS == -1 )); then
# No username ever
lp_username=''
return 2
elif (( LP_USER_ALWAYS )) || ! _lp_user; then
lp_username=${USER:-${USERNAME:-${LOGNAME-}}}
lp_username_raw=${USER:-${USERNAME:-${LOGNAME-}}}

if [[ -z $lp_username ]]; then
lp_username=$(id -nu 2>/dev/null)
if [[ -z $lp_username_raw ]]; then
lp_username_raw=$(id -nu 2>/dev/null)
fi

local ret
__lp_escape "$lp_username"
__lp_escape "$lp_username_raw"
lp_username=$ret

return 0
else
lp_username=''
return 1
fi
}
Expand Down Expand Up @@ -1259,15 +1254,15 @@ _lp_hostname() {
return 1
fi

lp_hostname=${HOSTNAME:-${HOST-}}
lp_hostname_raw=${HOSTNAME:-${HOST-}}

# Truncate to the first subdomain
if ! (( LP_ENABLE_FQDN )); then
lp_hostname=${lp_hostname%%.*}
lp_hostname_raw=${lp_hostname_raw%%.*}
fi

local ret
__lp_escape "$lp_hostname"
__lp_escape "$lp_hostname_raw"
lp_hostname=$ret
else
return 2
Expand Down Expand Up @@ -2709,7 +2704,7 @@ _lp_default_theme_directory() {
fi
fi

local lp_path lp_path_format
local lp_path_format
_lp_path_format "$LP_COLOR_PATH" "$LP_COLOR_PATH_LAST_DIR" "$LP_COLOR_PATH_VCS_ROOT" "$LP_COLOR_PATH_SHORTENED" "/" "$LP_COLOR_PATH_SEPARATOR"

LP_PWD="${lp_path_format}${NO_COL}"
Expand Down Expand Up @@ -2830,8 +2825,8 @@ _lp_default_theme_prompt_template() {
# add return code and prompt mark
PS1+="${LP_RUNTIME}${LP_ERR}${LP_MARK_PREFIX}${LP_COLOR_MARK}${LP_MARK}${LP_PS1_POSTFIX}"

# Get the current prompt on the fly and make it a title
_lp_formatted_title "$PS1"
# Get the core sections without prompt escapes and make them into a title.
_lp_formatted_title "${LP_PS1_PREFIX}${LP_MARK_BRACKET_OPEN}${lp_username_raw-}${lp_hostname_raw+@}${lp_hostname_raw-}${LP_MARK_PERM}${lp_path-}${LP_MARK_BRACKET_CLOSE}${LP_MARK_PREFIX}${lp_smart_mark} ${LP_PS1_POSTFIX}"

# Glue the bash prompt always go to the first column.
# Avoid glitches after interrupting a command with Ctrl-C
Expand Down
4 changes: 2 additions & 2 deletions tests/test_utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,10 @@ function test_path_format_from_path_left() {
LP_PATH_LENGTH=${#PWD}
_lp_path_format ''
if (( _LP_SHELL_zsh )); then
assertEquals "shell escapes" $'/a_fake_\\n_newline/and_%%100_fresh/and_a_real_\n_newline' "$lp_path"
assertEquals "shell escapes" $'/a_fake_\\n_newline/and_%100_fresh/and_a_real_\n_newline' "$lp_path"
assertEquals "shell escapes format" $'/a_fake_\\n_newline/and_%%100_fresh/and_a_real_\n_newline' "$lp_path_format"
else
assertEquals "shell escapes" $'/a_fake_\\\\n_newline/and_%100_fresh/and_a_real_\n_newline' "$lp_path"
assertEquals "shell escapes" $'/a_fake_\\n_newline/and_%100_fresh/and_a_real_\n_newline' "$lp_path"
assertEquals "shell escapes format" $'/a_fake_\\\\n_newline/and_%100_fresh/and_a_real_\n_newline' "$lp_path_format"
fi
}
Expand Down
11 changes: 4 additions & 7 deletions themes/powerline/powerline.theme
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,17 @@ __powerline_username_generate() {
_lp_powerline_theme_directory() {
# Not all terminals support Powerline special characters in the title
local title=
if [[ -n $_POWERLINE_USERNAME ]]; then
title+=${_POWERLINE_USERNAME}
fi
if [[ -n $_POWERLINE_HOSTNAME ]]; then
title+="@${_POWERLINE_HOSTNAME}"
fi
title+=${lp_username_raw-}
title+="${lp_hostname_raw+@}${lp_hostname_raw-}"

local lp_path
__powerline_path_generate

[[ -n $title ]] && title+=":"
title+="${lp_path}"

_lp_raw_title "$title"
# Include a trailing space to pad for the title command.
_lp_raw_title "$title "
}

_lp_powerline_theme_prompt() {
Expand Down

0 comments on commit a23af79

Please sign in to comment.