Class: Doing::Completion::BashCompletions

Inherits:
Object
  • Object
show all
Defined in:
lib/doing/completion/bash_completion.rb

Overview

Generate completions for Bash

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeBashCompletions

Returns a new instance of BashCompletions.



121
122
123
124
125
126
127
128
129
# File 'lib/doing/completion/bash_completion.rb', line 121

def initialize
  data = Completion.get_help_sections
  @global_options = Completion.parse_options(data[:global_options])
  @commands = Completion.parse_commands(data[:commands])
  @bar = TTY::ProgressBar.new("\033[0;0;33mGenerating Bash completions: \033[0;35;40m[:bar] :status\033[0m",
                              total: @commands.count + 1, bar_format: :square, hide_cursor: true, status: 'Reading subcommands')
  width = TTY::Screen.columns - 45
  @bar.resize(width)
end

Instance Attribute Details

#commandsObject

Returns the value of attribute commands.



7
8
9
# File 'lib/doing/completion/bash_completion.rb', line 7

def commands
  @commands
end

#global_optionsObject

Returns the value of attribute global_options.



7
8
9
# File 'lib/doing/completion/bash_completion.rb', line 7

def global_options
  @global_options
end

Instance Method Details

#command_function(command, options, type) ⇒ Object



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
# File 'lib/doing/completion/bash_completion.rb', line 61

def command_function(command, options, type)
  long_options = []
  short_options = []

  options.each do |o|
    next if o.nil?

    long_options << o[:long] if o[:long]
    short_options << o[:short] if o[:short]
  end

  long = long_options.map! { |o| "--#{o}" }.join(' ')
  short = short_options.map! { |o| "-#{o}" }.join(' ')
  words = ''
  logic = ''
  words, logic = get_words(type) if type.is_a?(String)

  <<~ENDFUNC
    _doing_#{command}() {
      #{words}
      if [[ "$token" == --* ]]; then
        COMPREPLY=( $( compgen -W '#{long}' -- $token ) )
      elif [[ "$token" == -* ]]; then
        COMPREPLY=( $( compgen -W '#{short} #{long}' -- $token ) )
      #{logic}
      fi
    }
  ENDFUNC
end

#generate_completionsObject



131
132
133
134
135
136
137
138
139
# File 'lib/doing/completion/bash_completion.rb', line 131

def generate_completions
  @bar.start
  out = []
  out << main_function
  out << 'complete -F _doing doing'
  @bar.advance(status: '')
  @bar.finish
  out.join("\n")
end

#get_words(type) ⇒ Object



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/doing/completion/bash_completion.rb', line 91

def get_words(type)
  func = <<~EOFUNC
    OLD_IFS="$IFS"
    local token=${COMP_WORDS[$COMP_CWORD]}
    IFS=$'\t'
    local words=$(doing #{type})
    IFS="$OLD_IFS"
  EOFUNC

  logic = <<~EOLOGIC
    else
      local nocasematchWasOff=0
      shopt nocasematch >/dev/null || nocasematchWasOff=1
      (( nocasematchWasOff )) && shopt -s nocasematch
      local w matches=()
      OLD_IFS="$IFS"
      IFS=$'\t'‰
      for w in $words; do
        if [[ "$w" == "$token"* ]]; then
          matches+=("${w// /\ }")
        fi
      done
      IFS="$OLD_IFS"
      (( nocasematchWasOff )) && shopt -u nocasematch
      COMPREPLY=("${matches[@]}")
  EOLOGIC

  [func, logic]
end

#main_functionObject



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
# File 'lib/doing/completion/bash_completion.rb', line 9

def main_function
  first = true
  out = []
  logic = []

  @commands.each_with_index do |cmd, _i|
    @bar.advance(status: cmd[:commands].first)

    data = Completion.get_help_sections(cmd[:commands].first)

    arg = data[:synopsis].join(' ').strip.split(/ /).last
    type = case arg
           when /(path|file)/i
             :file
           when /sect/i
             'sections'
           when /view/i
             'views'
           end

    next unless data[:command_options]

    options = Completion.parse_options(data[:command_options])
    out << command_function(cmd[:commands].first, options, type)

    if first
      op = 'if'
      first = false
    else
      op = 'elif'
    end
    logic << %(#{op} [[ $last =~ (#{cmd[:commands].join('|')}) ]]; then _doing_#{cmd[:commands].first})
  end

  out << <<~EOFUNC
    _doing()
    {
      local last="${@: -1}"
      local token=${COMP_WORDS[$COMP_CWORD]}

      #{logic.join("\n    ")}
      else
        OLD_IFS="$IFS"
        IFS=$'\n'
        COMPREPLY=( $(compgen -W "$(doing help -c)" -- $token) )
        IFS="$OLD_IFS"
      fi
    }
  EOFUNC
  out.join("\n")
end