doing 1.0.93 → 2.0.6.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/AUTHORS +19 -0
 - data/CHANGELOG.md +616 -0
 - data/COMMANDS.md +1181 -0
 - data/Gemfile +2 -0
 - data/Gemfile.lock +110 -0
 - data/LICENSE +23 -0
 - data/README.md +15 -699
 - data/Rakefile +79 -0
 - data/_config.yml +1 -0
 - data/bin/doing +1055 -494
 - data/doing.gemspec +34 -0
 - data/doing.rdoc +1839 -0
 - data/example_plugin.rb +209 -0
 - data/generate_completions.sh +5 -0
 - data/img/doing-colors.jpg +0 -0
 - data/img/doing-printf-wrap-800.jpg +0 -0
 - data/img/doing-show-note-formatting-800.jpg +0 -0
 - data/lib/completion/_doing.zsh +203 -0
 - data/lib/completion/doing.bash +449 -0
 - data/lib/completion/doing.fish +329 -0
 - data/lib/doing/array.rb +8 -0
 - data/lib/doing/cli_status.rb +70 -0
 - data/lib/doing/colors.rb +136 -0
 - data/lib/doing/configuration.rb +312 -0
 - data/lib/doing/errors.rb +109 -0
 - data/lib/doing/hash.rb +31 -0
 - data/lib/doing/hooks.rb +59 -0
 - data/lib/doing/item.rb +155 -0
 - data/lib/doing/log_adapter.rb +344 -0
 - data/lib/doing/markdown_document_listener.rb +174 -0
 - data/lib/doing/note.rb +59 -0
 - data/lib/doing/pager.rb +95 -0
 - data/lib/doing/plugin_manager.rb +208 -0
 - data/lib/doing/plugins/export/csv_export.rb +48 -0
 - data/lib/doing/plugins/export/html_export.rb +83 -0
 - data/lib/doing/plugins/export/json_export.rb +140 -0
 - data/lib/doing/plugins/export/markdown_export.rb +85 -0
 - data/lib/doing/plugins/export/taskpaper_export.rb +34 -0
 - data/lib/doing/plugins/export/template_export.rb +141 -0
 - data/lib/doing/plugins/import/cal_to_json.scpt +0 -0
 - data/lib/doing/plugins/import/calendar_import.rb +76 -0
 - data/lib/doing/plugins/import/doing_import.rb +144 -0
 - data/lib/doing/plugins/import/timing_import.rb +78 -0
 - data/lib/doing/string.rb +348 -0
 - data/lib/doing/symbol.rb +16 -0
 - data/lib/doing/time.rb +18 -0
 - data/lib/doing/util.rb +186 -0
 - data/lib/doing/version.rb +1 -1
 - data/lib/doing/wwid.rb +1868 -2349
 - data/lib/doing/wwidfile.rb +117 -0
 - data/lib/doing.rb +43 -3
 - data/lib/examples/commands/autotag.rb +63 -0
 - data/lib/examples/commands/wiki.rb +81 -0
 - data/lib/examples/plugins/hooks.rb +22 -0
 - data/lib/examples/plugins/say_export.rb +202 -0
 - data/lib/examples/plugins/templates/wiki.css +169 -0
 - data/lib/examples/plugins/templates/wiki.haml +27 -0
 - data/lib/examples/plugins/templates/wiki_index.haml +18 -0
 - data/lib/examples/plugins/wiki_export.rb +87 -0
 - data/lib/templates/doing-markdown.erb +5 -0
 - data/man/doing.1 +964 -0
 - data/man/doing.1.html +711 -0
 - data/man/doing.1.ronn +600 -0
 - data/package-lock.json +3 -0
 - data/rdoc_to_mmd.rb +42 -0
 - data/rdocfixer.rb +13 -0
 - data/scripts/generate_bash_completions.rb +211 -0
 - data/scripts/generate_fish_completions.rb +204 -0
 - data/scripts/generate_zsh_completions.rb +168 -0
 - metadata +82 -7
 - data/lib/doing/helpers.rb +0 -191
 - data/lib/doing/markdown_export.rb +0 -16
 
| 
         @@ -0,0 +1,211 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            $LOAD_PATH.unshift File.join(__dir__, '..', 'lib')
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'doing/cli_status'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require 'shellwords'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            class ::String
         
     | 
| 
      
 8 
     | 
    
         
            +
              def short_desc
         
     | 
| 
      
 9 
     | 
    
         
            +
                split(/[,.]/)[0].sub(/ \(.*?\)?$/, '').strip
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              def ltrunc(max)
         
     | 
| 
      
 13 
     | 
    
         
            +
                if length > max
         
     | 
| 
      
 14 
     | 
    
         
            +
                  sub(/^.*?(.{#{max - 3}})$/, '...\1')
         
     | 
| 
      
 15 
     | 
    
         
            +
                else
         
     | 
| 
      
 16 
     | 
    
         
            +
                  self
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              def ltrunc!(max)
         
     | 
| 
      
 21 
     | 
    
         
            +
                replace ltrunc(max)
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            class BashCompletions
         
     | 
| 
      
 26 
     | 
    
         
            +
              include Status
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              attr_accessor :commands, :global_options
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              def main_function
         
     | 
| 
      
 31 
     | 
    
         
            +
                first = true
         
     | 
| 
      
 32 
     | 
    
         
            +
                out = []
         
     | 
| 
      
 33 
     | 
    
         
            +
                logic = []
         
     | 
| 
      
 34 
     | 
    
         
            +
                need_export = []
         
     | 
| 
      
 35 
     | 
    
         
            +
                # processing = []
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                @commands.each_with_index do |cmd, i|
         
     | 
| 
      
 38 
     | 
    
         
            +
                  # processing << cmd[:commands].first
         
     | 
| 
      
 39 
     | 
    
         
            +
                  processing = cmd[:commands]
         
     | 
| 
      
 40 
     | 
    
         
            +
                  progress('Processing subcommand options', i, @commands.count, processing)
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  data = get_help_sections(cmd[:commands].first)
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  arg = data[:synopsis].join(' ').strip.split(/ /).last
         
     | 
| 
      
 45 
     | 
    
         
            +
                  case arg
         
     | 
| 
      
 46 
     | 
    
         
            +
                  when /(path|file)/i
         
     | 
| 
      
 47 
     | 
    
         
            +
                    type = :file
         
     | 
| 
      
 48 
     | 
    
         
            +
                  when /sect/i
         
     | 
| 
      
 49 
     | 
    
         
            +
                    type = 'sections'
         
     | 
| 
      
 50 
     | 
    
         
            +
                  when /view/i
         
     | 
| 
      
 51 
     | 
    
         
            +
                    type = 'views'
         
     | 
| 
      
 52 
     | 
    
         
            +
                  else
         
     | 
| 
      
 53 
     | 
    
         
            +
                    type = nil
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  if data[:command_options]
         
     | 
| 
      
 57 
     | 
    
         
            +
                    options = parse_options(data[:command_options])
         
     | 
| 
      
 58 
     | 
    
         
            +
                    out << command_function(cmd[:commands].first, options, type)
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                    if first
         
     | 
| 
      
 61 
     | 
    
         
            +
                      op = 'if'
         
     | 
| 
      
 62 
     | 
    
         
            +
                      first = false
         
     | 
| 
      
 63 
     | 
    
         
            +
                    else
         
     | 
| 
      
 64 
     | 
    
         
            +
                      op = 'elif'
         
     | 
| 
      
 65 
     | 
    
         
            +
                    end
         
     | 
| 
      
 66 
     | 
    
         
            +
                    logic << %(#{op} [[ $last =~ (#{cmd[:commands].join('|')}) ]]; then _doing_#{cmd[:commands].first})
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                out << <<~EOFUNC
         
     | 
| 
      
 71 
     | 
    
         
            +
                  _doing()
         
     | 
| 
      
 72 
     | 
    
         
            +
                  {
         
     | 
| 
      
 73 
     | 
    
         
            +
                    local last="${@: -1}"
         
     | 
| 
      
 74 
     | 
    
         
            +
                    local token=${COMP_WORDS[$COMP_CWORD]}
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                    #{logic.join("\n    ")}
         
     | 
| 
      
 77 
     | 
    
         
            +
                    else
         
     | 
| 
      
 78 
     | 
    
         
            +
                      OLD_IFS="$IFS"
         
     | 
| 
      
 79 
     | 
    
         
            +
                      IFS=$'\n'
         
     | 
| 
      
 80 
     | 
    
         
            +
                      COMPREPLY=( $(compgen -W "$(doing help -c)" -- $token) )
         
     | 
| 
      
 81 
     | 
    
         
            +
                      IFS="$OLD_IFS"
         
     | 
| 
      
 82 
     | 
    
         
            +
                    fi
         
     | 
| 
      
 83 
     | 
    
         
            +
                  }
         
     | 
| 
      
 84 
     | 
    
         
            +
                EOFUNC
         
     | 
| 
      
 85 
     | 
    
         
            +
                clear
         
     | 
| 
      
 86 
     | 
    
         
            +
                out.join("\n")
         
     | 
| 
      
 87 
     | 
    
         
            +
              end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
              def command_function(command, options, type)
         
     | 
| 
      
 90 
     | 
    
         
            +
                long_options = []
         
     | 
| 
      
 91 
     | 
    
         
            +
                short_options = []
         
     | 
| 
      
 92 
     | 
    
         
            +
                
         
     | 
| 
      
 93 
     | 
    
         
            +
                options.each do |o|
         
     | 
| 
      
 94 
     | 
    
         
            +
                  next if o.nil?
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                  long_options << o[:long] if o[:long]
         
     | 
| 
      
 97 
     | 
    
         
            +
                  short_options << o[:short] if o[:short]
         
     | 
| 
      
 98 
     | 
    
         
            +
                end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                long = long_options.map! {|o| "--#{o}"}.join(' ')
         
     | 
| 
      
 101 
     | 
    
         
            +
                short = short_options.map! {|o| "-#{o}"}.join(' ')
         
     | 
| 
      
 102 
     | 
    
         
            +
                words = ''
         
     | 
| 
      
 103 
     | 
    
         
            +
                logic = ''
         
     | 
| 
      
 104 
     | 
    
         
            +
                words, logic = get_words(type) if type && type.is_a?(String)
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                func = <<~ENDFUNC
         
     | 
| 
      
 107 
     | 
    
         
            +
                _doing_#{command}() {
         
     | 
| 
      
 108 
     | 
    
         
            +
                  #{words}
         
     | 
| 
      
 109 
     | 
    
         
            +
                  if [[ "$token" == --* ]]; then
         
     | 
| 
      
 110 
     | 
    
         
            +
                    COMPREPLY=( $( compgen -W '#{long}' -- $token ) )
         
     | 
| 
      
 111 
     | 
    
         
            +
                  elif [[ "$token" == -* ]]; then
         
     | 
| 
      
 112 
     | 
    
         
            +
                    COMPREPLY=( $( compgen -W '#{short} #{long}' -- $token ) )
         
     | 
| 
      
 113 
     | 
    
         
            +
                  #{logic}
         
     | 
| 
      
 114 
     | 
    
         
            +
                  fi
         
     | 
| 
      
 115 
     | 
    
         
            +
                }
         
     | 
| 
      
 116 
     | 
    
         
            +
                ENDFUNC
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                func
         
     | 
| 
      
 119 
     | 
    
         
            +
              end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
              def get_words(type)
         
     | 
| 
      
 122 
     | 
    
         
            +
                func = <<~EOFUNC
         
     | 
| 
      
 123 
     | 
    
         
            +
                  OLD_IFS="$IFS"
         
     | 
| 
      
 124 
     | 
    
         
            +
                  local token=${COMP_WORDS[$COMP_CWORD]}
         
     | 
| 
      
 125 
     | 
    
         
            +
                  IFS=$'\t'
         
     | 
| 
      
 126 
     | 
    
         
            +
                  local words=$(doing #{type})
         
     | 
| 
      
 127 
     | 
    
         
            +
                  IFS="$OLD_IFS"
         
     | 
| 
      
 128 
     | 
    
         
            +
                EOFUNC
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                logic = <<~EOLOGIC
         
     | 
| 
      
 131 
     | 
    
         
            +
                  else
         
     | 
| 
      
 132 
     | 
    
         
            +
                    local nocasematchWasOff=0
         
     | 
| 
      
 133 
     | 
    
         
            +
                    shopt nocasematch >/dev/null || nocasematchWasOff=1
         
     | 
| 
      
 134 
     | 
    
         
            +
                    (( nocasematchWasOff )) && shopt -s nocasematch
         
     | 
| 
      
 135 
     | 
    
         
            +
                    local w matches=()
         
     | 
| 
      
 136 
     | 
    
         
            +
                    OLD_IFS="$IFS"
         
     | 
| 
      
 137 
     | 
    
         
            +
                    IFS=$'\t'‰
         
     | 
| 
      
 138 
     | 
    
         
            +
                    for w in $words; do
         
     | 
| 
      
 139 
     | 
    
         
            +
                      if [[ "$w" == "$token"* ]]; then
         
     | 
| 
      
 140 
     | 
    
         
            +
                        matches+=("${w// /\ }")
         
     | 
| 
      
 141 
     | 
    
         
            +
                      fi
         
     | 
| 
      
 142 
     | 
    
         
            +
                    done
         
     | 
| 
      
 143 
     | 
    
         
            +
                    IFS="$OLD_IFS"
         
     | 
| 
      
 144 
     | 
    
         
            +
                    (( nocasematchWasOff )) && shopt -u nocasematch
         
     | 
| 
      
 145 
     | 
    
         
            +
                    COMPREPLY=("${matches[@]}")
         
     | 
| 
      
 146 
     | 
    
         
            +
                EOLOGIC
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                [func, logic]
         
     | 
| 
      
 149 
     | 
    
         
            +
              end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
              def get_help_sections(command = '')
         
     | 
| 
      
 154 
     | 
    
         
            +
                res = `doing help #{command}`.strip
         
     | 
| 
      
 155 
     | 
    
         
            +
                scanned = res.scan(/(?m-i)^([A-Z ]+)\n([\s\S]*?)(?=\n+[A-Z]+|\Z)/)
         
     | 
| 
      
 156 
     | 
    
         
            +
                sections = {}
         
     | 
| 
      
 157 
     | 
    
         
            +
                scanned.each do |sect|
         
     | 
| 
      
 158 
     | 
    
         
            +
                  title = sect[0].downcase.strip.gsub(/ +/, '_').to_sym
         
     | 
| 
      
 159 
     | 
    
         
            +
                  content = sect[1].split(/\n/).map(&:strip).delete_if(&:empty?)
         
     | 
| 
      
 160 
     | 
    
         
            +
                  sections[title] = content
         
     | 
| 
      
 161 
     | 
    
         
            +
                end
         
     | 
| 
      
 162 
     | 
    
         
            +
                sections
         
     | 
| 
      
 163 
     | 
    
         
            +
              end
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
              def parse_option(option)
         
     | 
| 
      
 166 
     | 
    
         
            +
                res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>[\w_]+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
         
     | 
| 
      
 167 
     | 
    
         
            +
                return nil unless res
         
     | 
| 
      
 168 
     | 
    
         
            +
                {
         
     | 
| 
      
 169 
     | 
    
         
            +
                  short: res['short'],
         
     | 
| 
      
 170 
     | 
    
         
            +
                  long: res['long'],
         
     | 
| 
      
 171 
     | 
    
         
            +
                  arg: res[:arg],
         
     | 
| 
      
 172 
     | 
    
         
            +
                  description: res['desc'].short_desc
         
     | 
| 
      
 173 
     | 
    
         
            +
                }
         
     | 
| 
      
 174 
     | 
    
         
            +
              end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
              def parse_options(options)
         
     | 
| 
      
 177 
     | 
    
         
            +
                options.map { |opt| parse_option(opt) }
         
     | 
| 
      
 178 
     | 
    
         
            +
              end
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
              def parse_command(command)
         
     | 
| 
      
 181 
     | 
    
         
            +
                res = command.match(/^(?<cmd>[^, \t]+)(?<alias>(?:, [^, \t]+)*)?\s+- (?<desc>.*?)$/)
         
     | 
| 
      
 182 
     | 
    
         
            +
                commands = [res['cmd']]
         
     | 
| 
      
 183 
     | 
    
         
            +
                commands.concat(res['alias'].split(/, /).delete_if(&:empty?)) if res['alias']
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
                {
         
     | 
| 
      
 186 
     | 
    
         
            +
                  commands: commands,
         
     | 
| 
      
 187 
     | 
    
         
            +
                  description: res['desc'].short_desc
         
     | 
| 
      
 188 
     | 
    
         
            +
                }
         
     | 
| 
      
 189 
     | 
    
         
            +
              end
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
              def parse_commands(commands)
         
     | 
| 
      
 192 
     | 
    
         
            +
                commands.map { |cmd| parse_command(cmd) }
         
     | 
| 
      
 193 
     | 
    
         
            +
              end
         
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
      
 195 
     | 
    
         
            +
              def initialize
         
     | 
| 
      
 196 
     | 
    
         
            +
                status('Generating Bash completions', reset: false)
         
     | 
| 
      
 197 
     | 
    
         
            +
                data = get_help_sections
         
     | 
| 
      
 198 
     | 
    
         
            +
                @global_options = parse_options(data[:global_options])
         
     | 
| 
      
 199 
     | 
    
         
            +
                @commands = parse_commands(data[:commands])
         
     | 
| 
      
 200 
     | 
    
         
            +
              end
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
              def generate_completions
         
     | 
| 
      
 203 
     | 
    
         
            +
                out = []
         
     | 
| 
      
 204 
     | 
    
         
            +
                out << main_function
         
     | 
| 
      
 205 
     | 
    
         
            +
                out << 'complete -F _doing doing'
         
     | 
| 
      
 206 
     | 
    
         
            +
                status('Complete', reset: false)
         
     | 
| 
      
 207 
     | 
    
         
            +
                out.join("\n")
         
     | 
| 
      
 208 
     | 
    
         
            +
              end
         
     | 
| 
      
 209 
     | 
    
         
            +
            end
         
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
      
 211 
     | 
    
         
            +
            puts BashCompletions.new.generate_completions
         
     | 
| 
         @@ -0,0 +1,204 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            $LOAD_PATH.unshift File.join(__dir__, '..', 'lib')
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'doing/cli_status'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require 'shellwords'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            class ::String
         
     | 
| 
      
 8 
     | 
    
         
            +
              def short_desc
         
     | 
| 
      
 9 
     | 
    
         
            +
                split(/[,.]/)[0].sub(/ \(.*?\)?$/, '').strip
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              def ltrunc(max)
         
     | 
| 
      
 13 
     | 
    
         
            +
                if length > max
         
     | 
| 
      
 14 
     | 
    
         
            +
                  sub(/^.*?(.{#{max - 3}})$/, '...\1')
         
     | 
| 
      
 15 
     | 
    
         
            +
                else
         
     | 
| 
      
 16 
     | 
    
         
            +
                  self
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              def ltrunc!(max)
         
     | 
| 
      
 21 
     | 
    
         
            +
                replace ltrunc(max)
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            class FishCompletions
         
     | 
| 
      
 26 
     | 
    
         
            +
              include Status
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              attr_accessor :commands, :global_options
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              def generate_helpers
         
     | 
| 
      
 31 
     | 
    
         
            +
                <<~EOFUNCTIONS
         
     | 
| 
      
 32 
     | 
    
         
            +
                  function __fish_doing_needs_command
         
     | 
| 
      
 33 
     | 
    
         
            +
                    # Figure out if the current invocation already has a command.
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                    set -l opts h-help config_file= f-doing_file= n-notes v-version stdout d-debug default x-noauto
         
     | 
| 
      
 36 
     | 
    
         
            +
                    set cmd (commandline -opc)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    set -e cmd[1]
         
     | 
| 
      
 38 
     | 
    
         
            +
                    argparse -s $opts -- $cmd 2>/dev/null
         
     | 
| 
      
 39 
     | 
    
         
            +
                    or return 0
         
     | 
| 
      
 40 
     | 
    
         
            +
                    # These flags function as commands, effectively.
         
     | 
| 
      
 41 
     | 
    
         
            +
                    if set -q argv[1]
         
     | 
| 
      
 42 
     | 
    
         
            +
                      # Also print the command, so this can be used to figure out what it is.
         
     | 
| 
      
 43 
     | 
    
         
            +
                      echo $argv[1]
         
     | 
| 
      
 44 
     | 
    
         
            +
                      return 1
         
     | 
| 
      
 45 
     | 
    
         
            +
                    end
         
     | 
| 
      
 46 
     | 
    
         
            +
                    return 0
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  function __fish_doing_using_command
         
     | 
| 
      
 50 
     | 
    
         
            +
                    set -l cmd (__fish_doing_needs_command)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    test -z "$cmd"
         
     | 
| 
      
 52 
     | 
    
         
            +
                    and return 1
         
     | 
| 
      
 53 
     | 
    
         
            +
                    contains -- $cmd $argv
         
     | 
| 
      
 54 
     | 
    
         
            +
                    and return 0
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  function __fish_doing_complete_sections
         
     | 
| 
      
 58 
     | 
    
         
            +
                    doing sections -c
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                  function __fish_doing_complete_views
         
     | 
| 
      
 62 
     | 
    
         
            +
                    doing views -c
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  function __fish_doing_subcommands
         
     | 
| 
      
 66 
     | 
    
         
            +
                    doing help -c
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  function __fish_doing_export_plugins
         
     | 
| 
      
 70 
     | 
    
         
            +
                    doing plugins --type export -c
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  function __fish_doing_import_plugins
         
     | 
| 
      
 74 
     | 
    
         
            +
                    doing plugins --type import -c
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  function __fish_doing_complete_templates
         
     | 
| 
      
 78 
     | 
    
         
            +
                    doing template -c
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                  complete -c doing -f
         
     | 
| 
      
 82 
     | 
    
         
            +
                  complete -xc doing -n '__fish_doing_needs_command' -a '(__fish_doing_subcommands)'
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                  complete -f -c doing -n '__fish_doing_using_command show' -a '(__fish_doing_complete_sections)'
         
     | 
| 
      
 85 
     | 
    
         
            +
                  complete -f -c doing -n '__fish_doing_using_command view' -a '(__fish_doing_complete_views)'
         
     | 
| 
      
 86 
     | 
    
         
            +
                  complete -f -c doing -n '__fish_doing_using_command template' -a '(__fish_doing_complete_templates)'
         
     | 
| 
      
 87 
     | 
    
         
            +
                  complete -f -c doing -s t -l type -x -n '__fish_doing_using_command import' -a '(__fish_doing_import_plugins)'
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                  complete -xc doing -n '__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from (doing help -c)' -a "(doing help -c)"
         
     | 
| 
      
 90 
     | 
    
         
            +
                EOFUNCTIONS
         
     | 
| 
      
 91 
     | 
    
         
            +
              end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
              def get_help_sections(command = '')
         
     | 
| 
      
 94 
     | 
    
         
            +
                res = `doing help #{command}`.strip
         
     | 
| 
      
 95 
     | 
    
         
            +
                scanned = res.scan(/(?m-i)^([A-Z ]+)\n([\s\S]*?)(?=\n+[A-Z]+|\Z)/)
         
     | 
| 
      
 96 
     | 
    
         
            +
                sections = {}
         
     | 
| 
      
 97 
     | 
    
         
            +
                scanned.each do |sect|
         
     | 
| 
      
 98 
     | 
    
         
            +
                  title = sect[0].downcase.strip.gsub(/ +/, '_').to_sym
         
     | 
| 
      
 99 
     | 
    
         
            +
                  content = sect[1].split(/\n/).map(&:strip).delete_if(&:empty?)
         
     | 
| 
      
 100 
     | 
    
         
            +
                  sections[title] = content
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
      
 102 
     | 
    
         
            +
                sections
         
     | 
| 
      
 103 
     | 
    
         
            +
              end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
              def parse_option(option)
         
     | 
| 
      
 106 
     | 
    
         
            +
                res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>[\w_]+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
         
     | 
| 
      
 107 
     | 
    
         
            +
                return nil unless res
         
     | 
| 
      
 108 
     | 
    
         
            +
                {
         
     | 
| 
      
 109 
     | 
    
         
            +
                  short: res['short'],
         
     | 
| 
      
 110 
     | 
    
         
            +
                  long: res['long'],
         
     | 
| 
      
 111 
     | 
    
         
            +
                  arg: res[:arg],
         
     | 
| 
      
 112 
     | 
    
         
            +
                  description: res['desc'].short_desc
         
     | 
| 
      
 113 
     | 
    
         
            +
                }
         
     | 
| 
      
 114 
     | 
    
         
            +
              end
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
              def parse_options(options)
         
     | 
| 
      
 117 
     | 
    
         
            +
                options.map { |opt| parse_option(opt) }
         
     | 
| 
      
 118 
     | 
    
         
            +
              end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
              def parse_command(command)
         
     | 
| 
      
 121 
     | 
    
         
            +
                res = command.match(/^(?<cmd>[^, \t]+)(?<alias>(?:, [^, \t]+)*)?\s+- (?<desc>.*?)$/)
         
     | 
| 
      
 122 
     | 
    
         
            +
                commands = [res['cmd']]
         
     | 
| 
      
 123 
     | 
    
         
            +
                commands.concat(res['alias'].split(/, /).delete_if(&:empty?)) if res['alias']
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                {
         
     | 
| 
      
 126 
     | 
    
         
            +
                  commands: commands,
         
     | 
| 
      
 127 
     | 
    
         
            +
                  description: res['desc'].short_desc
         
     | 
| 
      
 128 
     | 
    
         
            +
                }
         
     | 
| 
      
 129 
     | 
    
         
            +
              end
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
              def parse_commands(commands)
         
     | 
| 
      
 132 
     | 
    
         
            +
                commands.map { |cmd| parse_command(cmd) }
         
     | 
| 
      
 133 
     | 
    
         
            +
              end
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
              def generate_subcommand_completions
         
     | 
| 
      
 136 
     | 
    
         
            +
                out = []
         
     | 
| 
      
 137 
     | 
    
         
            +
                # processing = []
         
     | 
| 
      
 138 
     | 
    
         
            +
                @commands.each_with_index do |cmd, i|
         
     | 
| 
      
 139 
     | 
    
         
            +
                  # processing << cmd[:commands].first
         
     | 
| 
      
 140 
     | 
    
         
            +
                  processing = cmd[:commands]
         
     | 
| 
      
 141 
     | 
    
         
            +
                  progress('Processing subcommands', i, @commands.count, processing)
         
     | 
| 
      
 142 
     | 
    
         
            +
                  out << "complete -xc doing -n '__fish_doing_needs_command' -a '#{cmd[:commands].join(' ')}' -d #{Shellwords.escape(cmd[:description])}"
         
     | 
| 
      
 143 
     | 
    
         
            +
                end
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                out.join("\n")
         
     | 
| 
      
 146 
     | 
    
         
            +
              end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
              def generate_subcommand_option_completions
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                out = []
         
     | 
| 
      
 151 
     | 
    
         
            +
                need_export = []
         
     | 
| 
      
 152 
     | 
    
         
            +
                # processing = []
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                @commands.each_with_index do |cmd, i|
         
     | 
| 
      
 155 
     | 
    
         
            +
                  # processing << cmd[:commands].first
         
     | 
| 
      
 156 
     | 
    
         
            +
                  processing = cmd[:commands]
         
     | 
| 
      
 157 
     | 
    
         
            +
                  progress('Processing subcommand options', i, @commands.count, processing)
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                  data = get_help_sections(cmd[:commands].first)
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
                  if data[:synopsis].join(' ').strip.split(/ /).last =~ /(path|file)/i
         
     | 
| 
      
 162 
     | 
    
         
            +
                    out << "complete -c doing -F -n '__fish_doing_using_command #{cmd[:commands].join(" ")}'"
         
     | 
| 
      
 163 
     | 
    
         
            +
                  end
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
                  if data[:command_options]
         
     | 
| 
      
 166 
     | 
    
         
            +
                    parse_options(data[:command_options]).each do |option|
         
     | 
| 
      
 167 
     | 
    
         
            +
                      next if option.nil?
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
                      arg = option[:arg] ? '-r' : ''
         
     | 
| 
      
 170 
     | 
    
         
            +
                      short = option[:short] ? "-s #{option[:short]}" : ''
         
     | 
| 
      
 171 
     | 
    
         
            +
                      long = option[:long] ? "-l #{option[:long]}" : ''
         
     | 
| 
      
 172 
     | 
    
         
            +
                      out << "complete -c doing #{long} #{short} -f #{arg} -n '__fish_doing_using_command #{cmd[:commands].join(' ')}' -d #{Shellwords.escape(option[:description])}"
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                      need_export.concat(cmd[:commands]) if option[:long] == 'output'
         
     | 
| 
      
 175 
     | 
    
         
            +
                    end
         
     | 
| 
      
 176 
     | 
    
         
            +
                  end
         
     | 
| 
      
 177 
     | 
    
         
            +
                end
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
                unless need_export.empty?
         
     | 
| 
      
 180 
     | 
    
         
            +
                  out << "complete -f -c doing -s o -l output -x -n '__fish_doing_using_command #{need_export.join(' ')}' -a '(__fish_doing_export_plugins)'"
         
     | 
| 
      
 181 
     | 
    
         
            +
                end
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
                clear
         
     | 
| 
      
 184 
     | 
    
         
            +
                out.join("\n")
         
     | 
| 
      
 185 
     | 
    
         
            +
              end
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
              def initialize
         
     | 
| 
      
 188 
     | 
    
         
            +
                status('Generating Fish completions', reset: false)
         
     | 
| 
      
 189 
     | 
    
         
            +
                data = get_help_sections
         
     | 
| 
      
 190 
     | 
    
         
            +
                @global_options = parse_options(data[:global_options])
         
     | 
| 
      
 191 
     | 
    
         
            +
                @commands = parse_commands(data[:commands])
         
     | 
| 
      
 192 
     | 
    
         
            +
              end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
              def generate_completions
         
     | 
| 
      
 195 
     | 
    
         
            +
                out = []
         
     | 
| 
      
 196 
     | 
    
         
            +
                out << generate_helpers
         
     | 
| 
      
 197 
     | 
    
         
            +
                out << generate_subcommand_completions
         
     | 
| 
      
 198 
     | 
    
         
            +
                out << generate_subcommand_option_completions
         
     | 
| 
      
 199 
     | 
    
         
            +
                status('Complete', reset: false)
         
     | 
| 
      
 200 
     | 
    
         
            +
                out.join("\n")
         
     | 
| 
      
 201 
     | 
    
         
            +
              end
         
     | 
| 
      
 202 
     | 
    
         
            +
            end
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
            puts FishCompletions.new.generate_completions
         
     | 
| 
         @@ -0,0 +1,168 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            $LOAD_PATH.unshift File.join(__dir__, '..', 'lib')
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'doing/cli_status'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require 'shellwords'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            class ::String
         
     | 
| 
      
 8 
     | 
    
         
            +
              def short_desc
         
     | 
| 
      
 9 
     | 
    
         
            +
                split(/[,.]/)[0].sub(/ \(.*?\)?$/, '').strip
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              def ltrunc(max)
         
     | 
| 
      
 13 
     | 
    
         
            +
                if length > max
         
     | 
| 
      
 14 
     | 
    
         
            +
                  sub(/^.*?(.{#{max - 3}})$/, '...\1')
         
     | 
| 
      
 15 
     | 
    
         
            +
                else
         
     | 
| 
      
 16 
     | 
    
         
            +
                  self
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              def ltrunc!(max)
         
     | 
| 
      
 21 
     | 
    
         
            +
                replace ltrunc(max)
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            class ZshCompletions
         
     | 
| 
      
 26 
     | 
    
         
            +
              include Status
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              attr_accessor :commands, :global_options
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              def generate_helpers
         
     | 
| 
      
 31 
     | 
    
         
            +
                <<~EOFUNCTIONS
         
     | 
| 
      
 32 
     | 
    
         
            +
                  compdef _doing doing
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  function _doing() {
         
     | 
| 
      
 35 
     | 
    
         
            +
                      local line state
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                      function _commands {
         
     | 
| 
      
 38 
     | 
    
         
            +
                          local -a commands
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                          commands=(
         
     | 
| 
      
 41 
     | 
    
         
            +
                                    #{generate_subcommand_completions.join("\n                  ")}
         
     | 
| 
      
 42 
     | 
    
         
            +
                          )
         
     | 
| 
      
 43 
     | 
    
         
            +
                          _describe 'command' commands
         
     | 
| 
      
 44 
     | 
    
         
            +
                      }
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                      _arguments -C \
         
     | 
| 
      
 47 
     | 
    
         
            +
                              "1: :_commands" \
         
     | 
| 
      
 48 
     | 
    
         
            +
                              "*::arg:->args"
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                      case $line[1] in
         
     | 
| 
      
 53 
     | 
    
         
            +
                          #{generate_subcommand_option_completions(indent: '            ').join("\n            ")}
         
     | 
| 
      
 54 
     | 
    
         
            +
                      esac
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                      _arguments -s $args
         
     | 
| 
      
 57 
     | 
    
         
            +
                  }
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                EOFUNCTIONS
         
     | 
| 
      
 60 
     | 
    
         
            +
              end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
              def get_help_sections(command = '')
         
     | 
| 
      
 63 
     | 
    
         
            +
                res = `doing help #{command}`.strip
         
     | 
| 
      
 64 
     | 
    
         
            +
                scanned = res.scan(/(?m-i)^([A-Z ]+)\n([\s\S]*?)(?=\n+[A-Z]+|\Z)/)
         
     | 
| 
      
 65 
     | 
    
         
            +
                sections = {}
         
     | 
| 
      
 66 
     | 
    
         
            +
                scanned.each do |sect|
         
     | 
| 
      
 67 
     | 
    
         
            +
                  title = sect[0].downcase.strip.gsub(/ +/, '_').to_sym
         
     | 
| 
      
 68 
     | 
    
         
            +
                  content = sect[1].split(/\n/).map(&:strip).delete_if(&:empty?)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  sections[title] = content
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
                sections
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              def parse_option(option)
         
     | 
| 
      
 75 
     | 
    
         
            +
                res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>[\w_]+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
         
     | 
| 
      
 76 
     | 
    
         
            +
                return nil unless res
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                {
         
     | 
| 
      
 79 
     | 
    
         
            +
                  short: res['short'],
         
     | 
| 
      
 80 
     | 
    
         
            +
                  long: res['long'],
         
     | 
| 
      
 81 
     | 
    
         
            +
                  arg: res[:arg],
         
     | 
| 
      
 82 
     | 
    
         
            +
                  description: res['desc'].short_desc
         
     | 
| 
      
 83 
     | 
    
         
            +
                }
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
              def parse_options(options)
         
     | 
| 
      
 87 
     | 
    
         
            +
                options.map { |opt| parse_option(opt) }
         
     | 
| 
      
 88 
     | 
    
         
            +
              end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
              def parse_command(command)
         
     | 
| 
      
 91 
     | 
    
         
            +
                res = command.match(/^(?<cmd>[^, \t]+)(?<alias>(?:, [^, \t]+)*)?\s+- (?<desc>.*?)$/)
         
     | 
| 
      
 92 
     | 
    
         
            +
                commands = [res['cmd']]
         
     | 
| 
      
 93 
     | 
    
         
            +
                commands.concat(res['alias'].split(/, /).delete_if(&:empty?)) if res['alias']
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                {
         
     | 
| 
      
 96 
     | 
    
         
            +
                  commands: commands,
         
     | 
| 
      
 97 
     | 
    
         
            +
                  description: res['desc'].short_desc
         
     | 
| 
      
 98 
     | 
    
         
            +
                }
         
     | 
| 
      
 99 
     | 
    
         
            +
              end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
              def parse_commands(commands)
         
     | 
| 
      
 102 
     | 
    
         
            +
                commands.map { |cmd| parse_command(cmd) }
         
     | 
| 
      
 103 
     | 
    
         
            +
              end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
              def generate_subcommand_completions
         
     | 
| 
      
 106 
     | 
    
         
            +
                out = []
         
     | 
| 
      
 107 
     | 
    
         
            +
                # processing = []
         
     | 
| 
      
 108 
     | 
    
         
            +
                @commands.each_with_index do |cmd, i|
         
     | 
| 
      
 109 
     | 
    
         
            +
                  # processing << cmd[:commands].first
         
     | 
| 
      
 110 
     | 
    
         
            +
                  processing = cmd[:commands]
         
     | 
| 
      
 111 
     | 
    
         
            +
                  progress('Processing subcommands', i, @commands.count, processing)
         
     | 
| 
      
 112 
     | 
    
         
            +
                  cmd[:commands].each do |c|
         
     | 
| 
      
 113 
     | 
    
         
            +
                    out << "'#{c}:#{cmd[:description].gsub(/'/, '\\\'')}'"
         
     | 
| 
      
 114 
     | 
    
         
            +
                  end
         
     | 
| 
      
 115 
     | 
    
         
            +
                end
         
     | 
| 
      
 116 
     | 
    
         
            +
                clear
         
     | 
| 
      
 117 
     | 
    
         
            +
                out
         
     | 
| 
      
 118 
     | 
    
         
            +
              end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
              def generate_subcommand_option_completions(indent: '        ')
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                out = []
         
     | 
| 
      
 123 
     | 
    
         
            +
                # processing = []
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                @commands.each_with_index do |cmd, i|
         
     | 
| 
      
 126 
     | 
    
         
            +
                  # processing << cmd[:commands].first
         
     | 
| 
      
 127 
     | 
    
         
            +
                  processing = cmd[:commands]
         
     | 
| 
      
 128 
     | 
    
         
            +
                  progress('Processing subcommand options', i, @commands.count, processing)
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                  data = get_help_sections(cmd[:commands].first)
         
     | 
| 
      
 131 
     | 
    
         
            +
                  option_arr = []
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                  if data[:command_options]
         
     | 
| 
      
 134 
     | 
    
         
            +
                    parse_options(data[:command_options]).each do |option|
         
     | 
| 
      
 135 
     | 
    
         
            +
                      next if option.nil?
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
                      arg = option[:arg] ? '=' : ''
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                      option_arr << if option[:short]
         
     | 
| 
      
 140 
     | 
    
         
            +
                                      %({-#{option[:short]},--#{option[:long]}#{arg}}"[#{option[:description].gsub(/'/, '\\\'')}]")
         
     | 
| 
      
 141 
     | 
    
         
            +
                                    else
         
     | 
| 
      
 142 
     | 
    
         
            +
                                      %("(--#{option[:long]}#{arg})--#{option[:long]}#{arg}}[#{option[:description].gsub(/'/, '\\\'')}]")
         
     | 
| 
      
 143 
     | 
    
         
            +
                                    end
         
     | 
| 
      
 144 
     | 
    
         
            +
                    end
         
     | 
| 
      
 145 
     | 
    
         
            +
                  end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                  cmd[:commands].each do |c|
         
     | 
| 
      
 148 
     | 
    
         
            +
                    out << "#{c}) \n#{indent}    args=( #{option_arr.join(' ')} )\n#{indent};;"
         
     | 
| 
      
 149 
     | 
    
         
            +
                  end
         
     | 
| 
      
 150 
     | 
    
         
            +
                end
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                out
         
     | 
| 
      
 153 
     | 
    
         
            +
              end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
              def initialize
         
     | 
| 
      
 156 
     | 
    
         
            +
                status('Generating Zsh completions', reset: false)
         
     | 
| 
      
 157 
     | 
    
         
            +
                data = get_help_sections
         
     | 
| 
      
 158 
     | 
    
         
            +
                @global_options = parse_options(data[:global_options])
         
     | 
| 
      
 159 
     | 
    
         
            +
                @commands = parse_commands(data[:commands])
         
     | 
| 
      
 160 
     | 
    
         
            +
              end
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
              def generate_completions
         
     | 
| 
      
 163 
     | 
    
         
            +
                generate_helpers
         
     | 
| 
      
 164 
     | 
    
         
            +
                status('Complete', reset: false)
         
     | 
| 
      
 165 
     | 
    
         
            +
              end
         
     | 
| 
      
 166 
     | 
    
         
            +
            end
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
            puts ZshCompletions.new.generate_completions
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,15 +1,29 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: doing
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version:  
     | 
| 
      
 4 
     | 
    
         
            +
              version: 2.0.6.pre
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Brett Terpstra
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2021- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2021-11-18 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
      
 13 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 14 
     | 
    
         
            +
              name: safe_yaml
         
     | 
| 
      
 15 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 16 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 17 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 19 
     | 
    
         
            +
                    version: '1.0'
         
     | 
| 
      
 20 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 21 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 22 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 23 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 24 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 25 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 26 
     | 
    
         
            +
                    version: '1.0'
         
     | 
| 
       13 
27 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
28 
     | 
    
         
             
              name: rake
         
     | 
| 
       15 
29 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -162,16 +176,78 @@ extensions: [] 
     | 
|
| 
       162 
176 
     | 
    
         
             
            extra_rdoc_files:
         
     | 
| 
       163 
177 
     | 
    
         
             
            - README.md
         
     | 
| 
       164 
178 
     | 
    
         
             
            files:
         
     | 
| 
      
 179 
     | 
    
         
            +
            - AUTHORS
         
     | 
| 
      
 180 
     | 
    
         
            +
            - CHANGELOG.md
         
     | 
| 
      
 181 
     | 
    
         
            +
            - COMMANDS.md
         
     | 
| 
      
 182 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 183 
     | 
    
         
            +
            - Gemfile.lock
         
     | 
| 
      
 184 
     | 
    
         
            +
            - LICENSE
         
     | 
| 
       165 
185 
     | 
    
         
             
            - README.md
         
     | 
| 
      
 186 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 187 
     | 
    
         
            +
            - _config.yml
         
     | 
| 
       166 
188 
     | 
    
         
             
            - bin/doing
         
     | 
| 
      
 189 
     | 
    
         
            +
            - doing.gemspec
         
     | 
| 
      
 190 
     | 
    
         
            +
            - doing.rdoc
         
     | 
| 
      
 191 
     | 
    
         
            +
            - example_plugin.rb
         
     | 
| 
      
 192 
     | 
    
         
            +
            - generate_completions.sh
         
     | 
| 
      
 193 
     | 
    
         
            +
            - img/doing-colors.jpg
         
     | 
| 
      
 194 
     | 
    
         
            +
            - img/doing-printf-wrap-800.jpg
         
     | 
| 
      
 195 
     | 
    
         
            +
            - img/doing-show-note-formatting-800.jpg
         
     | 
| 
      
 196 
     | 
    
         
            +
            - lib/completion/_doing.zsh
         
     | 
| 
      
 197 
     | 
    
         
            +
            - lib/completion/doing.bash
         
     | 
| 
      
 198 
     | 
    
         
            +
            - lib/completion/doing.fish
         
     | 
| 
       167 
199 
     | 
    
         
             
            - lib/doing.rb
         
     | 
| 
       168 
     | 
    
         
            -
            - lib/doing/ 
     | 
| 
       169 
     | 
    
         
            -
            - lib/doing/ 
     | 
| 
      
 200 
     | 
    
         
            +
            - lib/doing/array.rb
         
     | 
| 
      
 201 
     | 
    
         
            +
            - lib/doing/cli_status.rb
         
     | 
| 
      
 202 
     | 
    
         
            +
            - lib/doing/colors.rb
         
     | 
| 
      
 203 
     | 
    
         
            +
            - lib/doing/configuration.rb
         
     | 
| 
      
 204 
     | 
    
         
            +
            - lib/doing/errors.rb
         
     | 
| 
      
 205 
     | 
    
         
            +
            - lib/doing/hash.rb
         
     | 
| 
      
 206 
     | 
    
         
            +
            - lib/doing/hooks.rb
         
     | 
| 
      
 207 
     | 
    
         
            +
            - lib/doing/item.rb
         
     | 
| 
      
 208 
     | 
    
         
            +
            - lib/doing/log_adapter.rb
         
     | 
| 
      
 209 
     | 
    
         
            +
            - lib/doing/markdown_document_listener.rb
         
     | 
| 
      
 210 
     | 
    
         
            +
            - lib/doing/note.rb
         
     | 
| 
      
 211 
     | 
    
         
            +
            - lib/doing/pager.rb
         
     | 
| 
      
 212 
     | 
    
         
            +
            - lib/doing/plugin_manager.rb
         
     | 
| 
      
 213 
     | 
    
         
            +
            - lib/doing/plugins/export/csv_export.rb
         
     | 
| 
      
 214 
     | 
    
         
            +
            - lib/doing/plugins/export/html_export.rb
         
     | 
| 
      
 215 
     | 
    
         
            +
            - lib/doing/plugins/export/json_export.rb
         
     | 
| 
      
 216 
     | 
    
         
            +
            - lib/doing/plugins/export/markdown_export.rb
         
     | 
| 
      
 217 
     | 
    
         
            +
            - lib/doing/plugins/export/taskpaper_export.rb
         
     | 
| 
      
 218 
     | 
    
         
            +
            - lib/doing/plugins/export/template_export.rb
         
     | 
| 
      
 219 
     | 
    
         
            +
            - lib/doing/plugins/import/cal_to_json.scpt
         
     | 
| 
      
 220 
     | 
    
         
            +
            - lib/doing/plugins/import/calendar_import.rb
         
     | 
| 
      
 221 
     | 
    
         
            +
            - lib/doing/plugins/import/doing_import.rb
         
     | 
| 
      
 222 
     | 
    
         
            +
            - lib/doing/plugins/import/timing_import.rb
         
     | 
| 
      
 223 
     | 
    
         
            +
            - lib/doing/string.rb
         
     | 
| 
      
 224 
     | 
    
         
            +
            - lib/doing/symbol.rb
         
     | 
| 
      
 225 
     | 
    
         
            +
            - lib/doing/time.rb
         
     | 
| 
      
 226 
     | 
    
         
            +
            - lib/doing/util.rb
         
     | 
| 
       170 
227 
     | 
    
         
             
            - lib/doing/version.rb
         
     | 
| 
       171 
228 
     | 
    
         
             
            - lib/doing/wwid.rb
         
     | 
| 
      
 229 
     | 
    
         
            +
            - lib/doing/wwidfile.rb
         
     | 
| 
      
 230 
     | 
    
         
            +
            - lib/examples/commands/autotag.rb
         
     | 
| 
      
 231 
     | 
    
         
            +
            - lib/examples/commands/wiki.rb
         
     | 
| 
      
 232 
     | 
    
         
            +
            - lib/examples/plugins/hooks.rb
         
     | 
| 
      
 233 
     | 
    
         
            +
            - lib/examples/plugins/say_export.rb
         
     | 
| 
      
 234 
     | 
    
         
            +
            - lib/examples/plugins/templates/wiki.css
         
     | 
| 
      
 235 
     | 
    
         
            +
            - lib/examples/plugins/templates/wiki.haml
         
     | 
| 
      
 236 
     | 
    
         
            +
            - lib/examples/plugins/templates/wiki_index.haml
         
     | 
| 
      
 237 
     | 
    
         
            +
            - lib/examples/plugins/wiki_export.rb
         
     | 
| 
       172 
238 
     | 
    
         
             
            - lib/helpers/fuzzyfilefinder
         
     | 
| 
      
 239 
     | 
    
         
            +
            - lib/templates/doing-markdown.erb
         
     | 
| 
       173 
240 
     | 
    
         
             
            - lib/templates/doing.css
         
     | 
| 
       174 
241 
     | 
    
         
             
            - lib/templates/doing.haml
         
     | 
| 
      
 242 
     | 
    
         
            +
            - man/doing.1
         
     | 
| 
      
 243 
     | 
    
         
            +
            - man/doing.1.html
         
     | 
| 
      
 244 
     | 
    
         
            +
            - man/doing.1.ronn
         
     | 
| 
      
 245 
     | 
    
         
            +
            - package-lock.json
         
     | 
| 
      
 246 
     | 
    
         
            +
            - rdoc_to_mmd.rb
         
     | 
| 
      
 247 
     | 
    
         
            +
            - rdocfixer.rb
         
     | 
| 
      
 248 
     | 
    
         
            +
            - scripts/generate_bash_completions.rb
         
     | 
| 
      
 249 
     | 
    
         
            +
            - scripts/generate_fish_completions.rb
         
     | 
| 
      
 250 
     | 
    
         
            +
            - scripts/generate_zsh_completions.rb
         
     | 
| 
       175 
251 
     | 
    
         
             
            homepage: http://brettterpstra.com/project/doing/
         
     | 
| 
       176 
252 
     | 
    
         
             
            licenses:
         
     | 
| 
       177 
253 
     | 
    
         
             
            - MIT
         
     | 
| 
         @@ -184,7 +260,6 @@ rdoc_options: 
     | 
|
| 
       184 
260 
     | 
    
         
             
            - README.md
         
     | 
| 
       185 
261 
     | 
    
         
             
            - "--markup"
         
     | 
| 
       186 
262 
     | 
    
         
             
            - markdown
         
     | 
| 
       187 
     | 
    
         
            -
            - "-ri"
         
     | 
| 
       188 
263 
     | 
    
         
             
            require_paths:
         
     | 
| 
       189 
264 
     | 
    
         
             
            - lib
         
     | 
| 
       190 
265 
     | 
    
         
             
            - lib
         
     | 
| 
         @@ -195,9 +270,9 @@ required_ruby_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       195 
270 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       196 
271 
     | 
    
         
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
       197 
272 
     | 
    
         
             
              requirements:
         
     | 
| 
       198 
     | 
    
         
            -
              - - " 
     | 
| 
      
 273 
     | 
    
         
            +
              - - ">"
         
     | 
| 
       199 
274 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       200 
     | 
    
         
            -
                  version:  
     | 
| 
      
 275 
     | 
    
         
            +
                  version: 1.3.1
         
     | 
| 
       201 
276 
     | 
    
         
             
            requirements: []
         
     | 
| 
       202 
277 
     | 
    
         
             
            rubygems_version: 3.2.16
         
     | 
| 
       203 
278 
     | 
    
         
             
            signing_key:
         
     |