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 Shell.annotate(<<~SCRIPT, kind: "adapter", shell: "bash", executable: executable)
			_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
	
	Shell.annotate(<<~SCRIPT, kind: "adapter", shell: "bash")
		_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
	Shell.annotate(<<~SCRIPT, kind: "helper", shell: "bash")
		__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