function zsh_urlencode() { emulate -L zsh local -a opts zparseopts -D -E -a opts r m P local in_str="$@" local url_str="" local spaces_as_plus if [[ -z $opts[(r)-P] ]]; then spaces_as_plus=1; fi local str="$in_str" # URLs must use UTF-8 encoding; convert str to UTF-8 if required local encoding=$langinfo[CODESET] # Use LC_CTYPE=C to process text byte-by-byte local i byte ord LC_ALL=C export LC_ALL local reserved=';/?:@&=+$,' local mark='_.!~*''()-' local dont_escape="[A-Za-z0-9" if [[ -z $opts[(r)-r] ]]; then dont_escape+=$reserved fi # $mark must be last because of the "-" if [[ -z $opts[(r)-m] ]]; then dont_escape+=$mark fi dont_escape+="]" # Implemented to use a single printf call and avoid subshells in the loop, # for performance local url_str="" for (( i = 1; i <= ${#str}; ++i )); do byte="$str[i]" if [[ "$byte" =~ "$dont_escape" ]]; then url_str+="$byte" else if [[ "$byte" == " " && -n $spaces_as_plus ]]; then url_str+="+" else ord=$(( [##16] #byte )) url_str+="%$ord" fi fi done echo -E "$url_str" } # Runs before showing the prompt function mzc_termsupport_precmd { [[ "${DISABLE_AUTO_TITLE:-}" == true ]] && return title $ZSH_THEME_TERM_TAB_TITLE_IDLE $ZSH_THEME_TERM_TITLE_IDLE } # Runs before executing the command function mzc_termsupport_preexec { [[ "${DISABLE_AUTO_TITLE:-}" == true ]] && return emulate -L zsh # split command into array of arguments local -a cmdargs cmdargs=("${(z)2}") # if running fg, extract the command from the job description if [[ "${cmdargs[1]}" = fg ]]; then # get the job id from the first argument passed to the fg command local job_id jobspec="${cmdargs[2]#%}" # logic based on jobs arguments: # http://zsh.sourceforge.net/Doc/Release/Jobs-_0026-Signals.html#Jobs # https://www.zsh.org/mla/users/2007/msg00704.html case "$jobspec" in <->) # %number argument: # use the same passed as an argument job_id=${jobspec} ;; ""|%|+) # empty, %% or %+ argument: # use the current job, which appears with a + in $jobstates: # suspended:+:5071=suspended (tty output) job_id=${(k)jobstates[(r)*:+:*]} ;; -) # %- argument: # use the previous job, which appears with a - in $jobstates: # suspended:-:6493=suspended (signal) job_id=${(k)jobstates[(r)*:-:*]} ;; [?]*) # %?string argument: # use $jobtexts to match for a job whose command *contains* job_id=${(k)jobtexts[(r)*${(Q)jobspec}*]} ;; *) # %string argument: # use $jobtexts to match for a job whose command *starts with* job_id=${(k)jobtexts[(r)${(Q)jobspec}*]} ;; esac # override preexec function arguments with job command if [[ -n "${jobtexts[$job_id]}" ]]; then 1="${jobtexts[$job_id]}" 2="${jobtexts[$job_id]}" fi fi # cmd name only, or if this is sudo or ssh, the next cmd local CMD=${1[(wr)^(*=*|sudo|ssh|mosh|rake|-*)]:gs/%/%%} local LINE="${2:gs/%/%%}" title '$CMD' '%100>...>$LINE%<<' } # Emits the control sequence to notify many terminal emulators # of the cwd # # Identifies the directory using a file: URI scheme, including # the host name to disambiguate local vs. remote paths. function mzc_termsupport_cwd { # Percent-encode the host and path names. local URL_HOST URL_PATH URL_HOST="$(zsh_urlencode -P $HOST)" || return 1 URL_PATH="$(zsh_urlencode -P $PWD)" || return 1 # common control sequence (OSC 7) to set current host and path printf "\e]7;%s\a" "file://${URL_HOST}${URL_PATH}" }