about summary refs log tree commit diff
path: root/Functions/TCP/tcp_alias
blob: 59fe678145bf10e163acc812750abf6422f8ee2e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# Create an alias for a TCP session.
#
# The syntax is similar to the `alias' builtin.  Aliases with a trailing
# `=' are assigned, while those without are listed.
#
# The alias can be used to refer to the session, however any output
# from the session will be shown using information for the base
# session name.  Likewise, any other reference to the session's file
# descriptor will cause the original session name rather than the alias to
# be used.
#
# It is an error to attempt to create an alias for a non-existent session.
# The alias will be removed when the session is closed.
#
# An alias can be reused without the session having to be closed.
# However, a base session name cannot be used as an alias.  If this
# becomes necessary, the base session should be renamed with tcp_rename
# first.
#
# With no arguments, list aliases.
#
# With the option -d, delete the alias.  No value is allowed in this case.
#
# With the option -q (quiet), just return status 1 on failure.  This
# does not apply to bad syntax, which is always reported.  Bad syntax
# includes deleting aliases when supplying a value.

emulate -L zsh
setopt extendedglob cbases

local opt quiet base value alias delete arg match mbegin mend fd array
integer stat index

while getopts "qd" opt; do
  case $opt in
    (q) quiet=1
	;;
    (d) delete=1
	;;
    (*) return 1
	;;
  esac
done
(( OPTIND > 1 )) && shift $(( OPTIND - 1 ))

if (( ! $# )); then
  if (( ${#tcp_aliases} )); then
    for fd value in ${(kv)tcp_aliases}; do
      for alias in ${=value}; do
	print -r - \
	"${alias}: alias for session ${tcp_by_fd[$fd]:-unnamed fd $fd}"
      done
    done
  fi
  return 0
fi

for arg in $*; do
  if [[ $arg = (#b)([^=]##)=(*) ]]; then
    if [[ -n $delete ]]; then
      print "$0: value given with deletion command." >&2
      stat=1
      continue
    fi
    alias=$match[1]
    base=$match[2]
    if [[ -z $base ]]; then
      # hmm, this is very nearly a syntax error...
      [[ -z $quiet ]] && print "$0: empty value for alias $alias" >&2
      stat=1
      continue
    fi
    if [[ ${+tcp_by_name} -eq 0 || -z ${tcp_by_name[$base]} ]]; then
      [[ -z $quiet ]] && print "$0: no base session \`$base' for alias"
      stat=1
      continue
    fi
    if [[ -n ${tcp_by_name[$alias]} ]]; then
      # already exists, OK if this is an alias...
      fd=${tcp_by_name[$alias]}
      array=(${=tcp_aliases[$fd]})
      if [[ -n ${array[(r)$alias]} ]]; then
	# yes, we're OK; delete the old alias.
	unset "tcp_by_name[$alias]"
	index=${array[(i)$alias]}
	array=(${array[1,index-1]} ${array[index+1,-1]})
	if [[ -z "$array" ]]; then
	  unset "tcp_aliases[$fd]"
	else
	  tcp_aliases[$fd]="$array"
	fi
      else
	# oops
	if [[ -z $quiet ]]; then
	  print "$0: \`$alias' is already a session name." >&2
	fi
	stat=1
	continue
      fi
    fi
    (( ! ${+tcp_aliases} )) && typeset -gA tcp_aliases
    fd=${tcp_by_name[$base]}
    if [[ -n ${tcp_aliases[$fd]} ]]; then
      tcp_aliases[$fd]+=" $alias"
    else
      tcp_aliases[$fd]=$alias
    fi
    tcp_by_name[$alias]=$fd
    if zmodload -i zsh/parameter; then
      if (( ${+functions[tcp_on_alias]} )); then
	tcp_on_alias $alias $fd
      fi
    fi
  else
    alias=$arg
    fd=${tcp_by_name[$alias]}
    if [[ -z $fd ]]; then
      print "$0: no such alias \`$alias'" >&2
      stat=1
      continue
    fi
    # OK if this is an alias...
    array=(${=tcp_aliases[$fd]})
    if [[ -n ${array[(r)$alias]} ]]; then
      # yes, we're OK
      if [[ -n $delete ]]; then
	unset "tcp_by_name[$alias]"
	index=${array[(i)$alias]}
	array=(${array[1,index-1]} ${array[index+1,-1]})
	if [[ -z "$array" ]]; then
	  unset "tcp_aliases[$fd]"
	else
	  tcp_aliases[$fd]="$array"
	fi

	if zmodload -i zsh/parameter; then
	  if (( ${+functions[tcp_on_unalias]} )); then
	    tcp_on_unalias $alias $fd
	  fi
	fi
      else
	print -r - \
	  "${alias}: alias for session ${tcp_by_fd[$fd]:-unnamed fd $fd}"
      fi
    else
      # oops
      if [[ -z $quiet ]]; then
	print "$0: \`$alias' is a session name." >&2
      fi
      stat=1
	continue
    fi
  fi
done

return $stat