termsupport.zsh 4.46 KB
Newer Older
1
2
3
4
5
6
7
8
# Set terminal window and tab/icon title
#
# usage: title short_tab_title [long_window_title]
#
# See: http://www.faqs.org/docs/Linux-mini/Xterm-Title.html#ss3.1
# Fully supports screen, iterm, and probably most modern xterm and rxvt
# (In screen, only short_tab_title is used)
# Limited support for Apple Terminal (Terminal can't set window and tab separately)
9
function title {
10
  emulate -L zsh
11
  setopt prompt_subst
12

Marc Cornellà's avatar
Marc Cornellà committed
13
14
15
16
17
18
  [[ "$EMACS" == *term* ]] && return

  # if $2 is unset use $1 as default
  # if it is set and empty, leave it as is
  : ${2=$1}

19
20
21
22
23
  case "$TERM" in
    cygwin|xterm*|putty*|rxvt*|ansi)
      print -Pn "\e]2;$2:q\a" # set window name
      print -Pn "\e]1;$1:q\a" # set tab name
      ;;
24
    screen*|tmux*)
25
26
27
28
29
30
      print -Pn "\ek$1:q\e\\" # set screen hardstatus
      ;;
    *)
      if [[ "$TERM_PROGRAM" == "iTerm.app" ]]; then
        print -Pn "\e]2;$2:q\a" # set window name
        print -Pn "\e]1;$1:q\a" # set tab name
31
32
33
34
      else
        # Try to use terminfo to set the title
        # If the feature is available set title
        if [[ -n "$terminfo[fsl]" ]] && [[ -n "$terminfo[tsl]" ]]; then
moyamo's avatar
moyamo committed
35
36
37
38
	  echoti tsl
	  print -Pn "$1"
	  echoti fsl
	fi
39
40
41
      fi
      ;;
  esac
42
43
44
45
}

ZSH_THEME_TERM_TAB_TITLE_IDLE="%15<..<%~%<<" #15 char left truncated PWD
ZSH_THEME_TERM_TITLE_IDLE="%n@%m: %~"
46
# Avoid duplication of directory in terminals with independent dir display
47
if [[ "$TERM_PROGRAM" == Apple_Terminal ]]; then
48
49
  ZSH_THEME_TERM_TITLE_IDLE="%n@%m"
fi
50

51
# Runs before showing the prompt
52
function omz_termsupport_precmd {
53
  emulate -L zsh
54
55

  if [[ "$DISABLE_AUTO_TITLE" == true ]]; then
56
57
58
    return
  fi

59
  title $ZSH_THEME_TERM_TAB_TITLE_IDLE $ZSH_THEME_TERM_TITLE_IDLE
60
61
}

62
# Runs before executing the command
63
function omz_termsupport_preexec {
64
  emulate -L zsh
65
66
67
  setopt extended_glob

  if [[ "$DISABLE_AUTO_TITLE" == true ]]; then
68
69
70
    return
  fi

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  # 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 <number> 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* <string>
        job_id=${(k)jobtexts[(r)*${(Q)jobspec}*]} ;;
      *) # %string argument:
        # use $jobtexts to match for a job whose command *starts with* <string>
        job_id=${(k)jobtexts[(r)${(Q)jobspec}*]} ;;
    esac
Marc Cornellà's avatar
Marc Cornellà committed
100

101
102
103
104
105
    # override preexec function arguments with job command
    local job_cmd="${jobtexts[$job_id]}"
    if [[ -n "$job_cmd" ]]; then
      1="$job_cmd"
      2="$job_cmd"
106
107
    fi
  fi
108

109
110
111
112
  # 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/%/%%}"

113
  title '$CMD' '%100>...>$LINE%<<'
114
}
115

Jingwen Owen Ou's avatar
Jingwen Owen Ou committed
116
117
precmd_functions+=(omz_termsupport_precmd)
preexec_functions+=(omz_termsupport_preexec)
118
119


120
# Keep Apple Terminal.app's current working directory updated
Janosch Schwalm's avatar
Janosch Schwalm committed
121
# Based on this answer: https://superuser.com/a/315029
122
# With extra fixes to handle multibyte chars and non-UTF-8 locales
123
124

if [[ "$TERM_PROGRAM" == "Apple_Terminal" ]] && [[ -z "$INSIDE_EMACS" ]]; then
125
  # Emits the control sequence to notify Terminal.app of the cwd
126
127
  # Identifies the directory using a file: URI scheme, including
  # the host name to disambiguate local vs. remote paths.
128
  function update_terminalapp_cwd() {
129
    emulate -L zsh
130
131

    # Percent-encode the pathname.
132
    local URL_PATH="$(omz_urlencode -P $PWD)"
133
    [[ $? != 0 ]] && return 1
134

135
    # Undocumented Terminal.app-specific control sequence
136
    printf '\e]7;%s\a' "file://$HOST$URL_PATH"
137
138
139
140
141
142
  }

  # Use a precmd hook instead of a chpwd hook to avoid contaminating output
  precmd_functions+=(update_terminalapp_cwd)
  # Run once to get initial cwd set
  update_terminalapp_cwd
143
fi