summaryrefslogtreecommitdiff
path: root/contrib/ri
blob: 9ec520c01e024e03ff2ecc367e14616bbb40d33b (plain)
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
# -*- mode: shell-script; sh-basic-offset: 8; indent-tabs-mode: t -*-
# ex: ts=8 sw=8 noet filetype=sh
#
# ri completion for Ruby documentation by Ian Macdonald <ian@caliban.org>

ri_get_methods()
{
	local regex

	if [ "$ri_version" = integrated ]; then
	  if [ -z "$separator" ]; then
	    regex="(Instance|Class)"
	  elif [ "$separator" = "#" ]; then
	    regex=Instance
	  else
	    regex=Class
	  fi

	  COMPREPLY=( ${COMPREPLY[@]} \
	    "$( ri ${classes[@]} 2>/dev/null | \
	      ruby -ane 'if /^'"$regex"' methods:/.../^------------------|^$/ and \
	      /^ / then print $_.split(/, |,$/).grep(/^[^\[]*$/).join("\n"); \
	      end' | sort -u )" )
	else
	  # older versions of ri didn't distinguish between class/module and
	  # instance methods
	  COMPREPLY=( ${COMPREPLY[@]} \
	    "$( ruby -W0 $ri_path ${classes[@]} | ruby -ane 'if /^-/.../^-/ and \
	      ! /^-/ and ! /^ +(class|module): / then \
	      print $_.split(/, |,$| +/).grep(/^[^\[]*$/).join("\n"); \
	      end' | sort -u )" )
	fi
	COMPREPLY=( $( compgen $prefix -W '${COMPREPLY[@]}' -- $method ) )
}

# needs at least Ruby 1.8.0 in order to use -W0
_ri()
{
	local cur class method prefix ri_path ri_version separator IFS
	local -a classes

	COMPREPLY=()
	cur=`_get_cword`

	ri_path=$(type -p ri)
	# which version of ri are we using?
	# -W0 is required here to stop warnings from older versions of ri
	# from being captured when used with Ruby 1.8.1 and later
	ri_version="$(ruby -W0 $ri_path -v 2>&1)" || ri_version=integrated
	[ "$ri_version" != "${ri_version%200*}" ] && ri_version=integrated

	# need to also split on commas
	IFS=$', \n\t'
	if [[ "$cur" == [A-Z]*[#.]* ]]; then
	  [[ "$cur" == *#* ]] && separator=# || separator=.
	  # we're completing on class and method
	  class=${cur%$separator*}
	  method=${cur#*$separator}
	  classes=( $class )
	  prefix="-P $class$separator"
	  ri_get_methods 
	  return 0
	fi

	if [ "$ri_version" = integrated ]; then
	  # integrated ri from Ruby 1.9
	  classes=( $( ri -c | ruby -ne 'if /^\s*$/..$stdin.eof then \
				      if /, [A-Z]+/ then print; end; end' ) )
	elif [ "$ri_version" = "ri 1.8a" ]; then
	  classes=( $( ruby -W0 $ri_path | \
		       ruby -ne 'if /^'"'"'ri'"'"' has/..$stdin.eof then \
				 if /^ .*[A-Z]/ then print; end; end' ))
	else
	  classes=( $( ruby -W0 $ri_path | \
		       ruby -ne 'if /^I have/..$stdin.eof then \
				 if /^ .*[A-Z]/ then print; end; end' ))
	fi

	COMPREPLY=( $( compgen -W '${classes[@]}' -- $cur ) )
	if [[ "$cur" == [A-Z]* ]]; then
	  # we're completing on class or module alone
	  return 0
	fi

	# we're completing on methods
	method=$cur
	ri_get_methods
}
complete -F _ri ri