Module: Completion::Shell::Bash

Defined in:
lib/completion/shell/bash.rb

Overview

Bash completion adapter generation.

Class Method Summary collapse

Class Method Details

.script(executable) ⇒ Object

Generate a Bash completion adapter script.



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
# File 'lib/completion/shell/bash.rb', line 14

def self.script(executable)
	command = Shell.command_name(executable)
	
	if executable
		return <<~SCRIPT
			_completion_source="${BASH_SOURCE[0]}"
			if [[ "$_completion_source" == */* ]]; then
				_completion_directory="${_completion_source%/*}"
			else
				_completion_directory="."
			fi
			source "${_completion_directory}/completion.bash"
			__completion_register #{command}
		SCRIPT
	end
	
	<<~SCRIPT
		_completion_source="${BASH_SOURCE[0]}"
		if [[ "$_completion_source" == */* ]]; then
			_completion_directory="${_completion_source%/*}"
		else
			_completion_directory="."
		fi
		source "${_completion_directory}/completion.bash"
		__completion_register_default
	SCRIPT
end

.shared_scriptObject

Generate the shared Bash helper script.



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
# File 'lib/completion/shell/bash.rb', line 45

def self.shared_script
	<<~SCRIPT
		__completion_resolve() {
			local command="$1"
			local basename="${command##*/}"
			
			if [[ "$command" == */* ]]; then
				printf "%s\\n" "${command%/*}/completion-${basename}"
			else
				printf "%s\\n" "completion-${basename}"
			fi
		}
		
		__completion_complete() {
			local command="${COMP_WORDS[0]}"
			local completer="$(__completion_resolve "$command")"
			
			[[ -x "$completer" ]] || return 0
			
			local argv=("${COMP_WORDS[@]:1:COMP_CWORD}")
			COMPREPLY=()
			
			while IFS=$'\\t' read -r type value description metadata; do
				case "$type" in
					path)
						while IFS= read -r completion; do
							COMPREPLY+=("$completion")
						done < <(compgen -f -- "$value")
						;;
					directory)
						while IFS= read -r completion; do
							COMPREPLY+=("$completion")
						done < <(compgen -d -- "$value")
						;;
					executable)
						while IFS= read -r completion; do
							COMPREPLY+=("$completion")
						done < <(compgen -c -- "$value")
						;;
					delegate)
						if [[ "$metadata" == *index=* ]]; then
							local index="${metadata##*index=}"
							index="${index%%$'\\t'*}"
							local offset=$((index + 1))
							COMP_WORDS=("${COMP_WORDS[@]:$offset}")
							COMP_CWORD=$((COMP_CWORD - offset))
							
							if declare -F _completion_loader >/dev/null; then
								_completion_loader "${COMP_WORDS[0]}" >/dev/null 2>&1 || true
							fi
							
							local specification
							specification="$(complete -p "${COMP_WORDS[0]}" 2>/dev/null || true)"
							
							if [[ "$specification" =~ -F[[:space:]]+([^[:space:]]+) ]]; then
								"${BASH_REMATCH[1]}"
							fi
						fi
						;;
					*)
						COMPREPLY+=("$value")
						;;
				esac
			done < <("$completer" "${argv[@]}")
		}
		
		__completion_register() {
			complete -F __completion_complete "$1"
		}
		
		__completion_register_default() {
			complete -D -o bashdefault -o default -F __completion_complete 2>/dev/null || true
		}
	SCRIPT
end