about summary refs log tree commit diff
path: root/Completion/Unix/Type/_bind_addresses
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/Unix/Type/_bind_addresses')
-rw-r--r--Completion/Unix/Type/_bind_addresses37
1 files changed, 35 insertions, 2 deletions
diff --git a/Completion/Unix/Type/_bind_addresses b/Completion/Unix/Type/_bind_addresses
index 6042eaf1e..d12727800 100644
--- a/Completion/Unix/Type/_bind_addresses
+++ b/Completion/Unix/Type/_bind_addresses
@@ -1,9 +1,21 @@
 #autoload
 
-# @todo In the future it might be useful to have this function take a glob or
-# similar to filter out loop-back addresses, only return IPv4/6, etc.
+# Complete locally bound IP addresses
+#
+# Options:
+#   -0  Return also `0.0.0.0` and `::`
+#   -4  Return only IPv4 addresses
+#   -6  Return only IPv6 addresses
+#   -b  Return IPv6 addresses in brackets (for use with port numbers)
+#   -h  Return also `localhost`
+#   -L  Exclude loop-back addresses (`127.0.0.0/8` and `::1`)
+#   -K  Exclude link-local addresses (`169.254.0.0/16` and `fe80::/10`)
 
+local MATCH MBEGIN MEND
 local -a expl tmp cmd=( ifconfig -a )
+local -A opts
+
+zparseopts -A opts -D -E -- 0 4 6 b h L K
 
 # A lot of Linux systems have ifconfig, but this is probably safer (and it's
 # parsed the same way)
@@ -14,4 +26,25 @@ tmp=( ${(@M)tmp##(|[[:space:]]##)inet(|6)(|:)[[:space:]]*} )
 tmp=( ${(@)tmp#*inet(|6)(|:)[[:space:]]##} )
 tmp=( ${(@)tmp%%[^0-9A-Fa-f:.]*} )
 
+# The order of operations here is significant
+(( $+opts[-0] )) && tmp+=( 0.0.0.0 :: )
+
+if (( $+opts[-6] )); then
+  tmp=( ${(@M)tmp:#*:*} )
+elif (( $+opts[-4] )); then
+  tmp=( ${(@)tmp:#*:*} )
+fi
+
+(( $+opts[-L] )) && {
+  tmp=( ${(@)tmp:#127.*} )
+  tmp=( ${(@)tmp:#[0:]##:1} )
+}
+(( $+opts[-K] )) && {
+  tmp=( ${(@)tmp:#169.254.*} )
+  tmp=( ${(@)tmp:#(#i)fe[89ab]?:*} )
+}
+
+(( $+opts[-b] )) && tmp=( ${(@)tmp/(#m)*:*/\[$MATCH\]} )
+(( $+opts[-h] )) && tmp+=( localhost )
+
 _wanted bind-addresses expl 'bind address' compadd -a "$@" - tmp