1## vim:ft=zsh
2## perforce support by: Phil Pennock
3## Distributed under the same BSD-ish license as zsh itself.
4
5# If use-server is true in the :vcs_info:p4:... context, contact the
6# server to decide whether the directory is handled by Perforce.  This can
7# cause a delay if the network times out, in particular if looking up the
8# server name failed.  Hence this is not the default.  If a timeout
9# occurred, the server:port pair is added to the associative array
10# vcs_info_p4_dead_servers and the server is never contacted again.  The
11# array must be edited by hand to remove it.
12#
13# If use-server is false or not set, the function looks to see if there is
14# a file $P4CONFIG somewhere above in the hierarchy.  This is far from
15# foolproof; in fact it relies on you using the particular working practice
16# of having such files in all client root directories and nowhere above.
17
18
19(( ${+functions[VCS_INFO_p4_get_server]} )) ||
20VCS_INFO_p4_get_server() {
21  emulate -L zsh
22  setopt extendedglob
23
24  local -a settings
25  settings=(${(f)"$(${vcs_comm[cmd]} set)"})
26  serverport=${${settings[(r)P4PORT=*]##P4PORT=}%% *}
27  case $serverport in
28    (''|:)
29    serverport=perforce:1666
30    ;;
31
32    (:*)
33    serverport=perforce${serverport}
34    ;;
35
36    (*:)
37    serverport=${serverport}1666
38    ;;
39
40    (<->)
41    serverport=perforce:${serverport}
42    ;;
43  esac
44}
45
46
47VCS_INFO_detect_p4() {
48  local serverport p4where
49
50  if zstyle -t ":vcs_info:p4:${usercontext}:${rrn}" use-server; then
51    # Use "p4 where" to decide whether the path is under the
52    # client workspace.
53    if (( ${#vcs_info_p4_dead_servers} )); then
54      # See if the server is in the list of defunct servers
55      VCS_INFO_p4_get_server
56      [[ -n $vcs_info_p4_dead_servers[$serverport] ]] && return 1
57    fi
58    if p4where="$(${vcs_comm[cmd]} where 2>&1)"; then
59      return 0
60    fi
61    if [[ $p4where = *"Connect to server failed"* ]]; then
62      # If the connection failed, mark the server as defunct.
63      # Otherwise it worked but we weren't within a client.
64      typeset -gA vcs_info_p4_dead_servers
65      [[ -z $serverport ]] && VCS_INFO_p4_get_server
66      vcs_info_p4_dead_servers[$serverport]=1
67    fi
68    return 1
69  else
70    [[ -n ${P4CONFIG} ]] || return 1
71    VCS_INFO_check_com ${vcs_comm[cmd]} || return 1
72    vcs_comm[detect_need_file]="${P4CONFIG}"
73    VCS_INFO_bydir_detect .
74    return $?
75  fi
76}
77
78VCS_INFO_detect_p4 "$@"
79