doing 2.0.18 → 2.0.22

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.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/Gemfile.lock +15 -5
  4. data/README.md +1 -1
  5. data/bin/doing +2 -18
  6. data/doing.gemspec +5 -4
  7. data/doing.rdoc +2 -2
  8. data/generate_completions.sh +3 -3
  9. data/lib/doing/cli_status.rb +6 -2
  10. data/lib/doing/completion/bash_completion.rb +185 -0
  11. data/lib/doing/completion/fish_completion.rb +175 -0
  12. data/lib/doing/completion/string.rb +17 -0
  13. data/lib/doing/completion/zsh_completion.rb +140 -0
  14. data/lib/doing/completion.rb +39 -0
  15. data/lib/doing/version.rb +1 -1
  16. data/lib/doing/wwid.rb +18 -6
  17. data/lib/doing.rb +1 -1
  18. data/lib/helpers/fzf/.goreleaser.yml +119 -0
  19. data/lib/helpers/fzf/.rubocop.yml +28 -0
  20. data/lib/helpers/fzf/ADVANCED.md +565 -0
  21. data/lib/helpers/fzf/BUILD.md +49 -0
  22. data/lib/helpers/fzf/CHANGELOG.md +1193 -0
  23. data/lib/helpers/fzf/Dockerfile +11 -0
  24. data/lib/helpers/fzf/LICENSE +21 -0
  25. data/lib/helpers/fzf/Makefile +166 -0
  26. data/lib/helpers/fzf/README-VIM.md +486 -0
  27. data/lib/helpers/fzf/README.md +712 -0
  28. data/lib/helpers/fzf/bin/fzf-tmux +233 -0
  29. data/lib/helpers/fzf/doc/fzf.txt +512 -0
  30. data/lib/helpers/fzf/go.mod +17 -0
  31. data/lib/helpers/fzf/go.sum +31 -0
  32. data/lib/helpers/fzf/install +382 -0
  33. data/lib/helpers/fzf/install.ps1 +65 -0
  34. data/lib/helpers/fzf/main.go +14 -0
  35. data/lib/helpers/fzf/man/man1/fzf-tmux.1 +68 -0
  36. data/lib/helpers/fzf/man/man1/fzf.1 +1001 -0
  37. data/lib/helpers/fzf/plugin/fzf.vim +1048 -0
  38. data/lib/helpers/fzf/shell/completion.bash +381 -0
  39. data/lib/helpers/fzf/shell/completion.zsh +329 -0
  40. data/lib/helpers/fzf/shell/key-bindings.bash +96 -0
  41. data/lib/helpers/fzf/shell/key-bindings.fish +172 -0
  42. data/lib/helpers/fzf/shell/key-bindings.zsh +114 -0
  43. data/lib/helpers/fzf/src/LICENSE +21 -0
  44. data/lib/helpers/fzf/src/algo/algo.go +884 -0
  45. data/lib/helpers/fzf/src/algo/algo_test.go +197 -0
  46. data/lib/helpers/fzf/src/algo/normalize.go +492 -0
  47. data/lib/helpers/fzf/src/ansi.go +409 -0
  48. data/lib/helpers/fzf/src/ansi_test.go +427 -0
  49. data/lib/helpers/fzf/src/cache.go +81 -0
  50. data/lib/helpers/fzf/src/cache_test.go +39 -0
  51. data/lib/helpers/fzf/src/chunklist.go +89 -0
  52. data/lib/helpers/fzf/src/chunklist_test.go +80 -0
  53. data/lib/helpers/fzf/src/constants.go +85 -0
  54. data/lib/helpers/fzf/src/core.go +351 -0
  55. data/lib/helpers/fzf/src/history.go +96 -0
  56. data/lib/helpers/fzf/src/history_test.go +68 -0
  57. data/lib/helpers/fzf/src/item.go +44 -0
  58. data/lib/helpers/fzf/src/item_test.go +23 -0
  59. data/lib/helpers/fzf/src/matcher.go +235 -0
  60. data/lib/helpers/fzf/src/merger.go +120 -0
  61. data/lib/helpers/fzf/src/merger_test.go +88 -0
  62. data/lib/helpers/fzf/src/options.go +1691 -0
  63. data/lib/helpers/fzf/src/options_test.go +457 -0
  64. data/lib/helpers/fzf/src/pattern.go +425 -0
  65. data/lib/helpers/fzf/src/pattern_test.go +209 -0
  66. data/lib/helpers/fzf/src/protector/protector.go +8 -0
  67. data/lib/helpers/fzf/src/protector/protector_openbsd.go +10 -0
  68. data/lib/helpers/fzf/src/reader.go +201 -0
  69. data/lib/helpers/fzf/src/reader_test.go +63 -0
  70. data/lib/helpers/fzf/src/result.go +243 -0
  71. data/lib/helpers/fzf/src/result_others.go +16 -0
  72. data/lib/helpers/fzf/src/result_test.go +159 -0
  73. data/lib/helpers/fzf/src/result_x86.go +16 -0
  74. data/lib/helpers/fzf/src/terminal.go +2832 -0
  75. data/lib/helpers/fzf/src/terminal_test.go +638 -0
  76. data/lib/helpers/fzf/src/terminal_unix.go +26 -0
  77. data/lib/helpers/fzf/src/terminal_windows.go +45 -0
  78. data/lib/helpers/fzf/src/tokenizer.go +253 -0
  79. data/lib/helpers/fzf/src/tokenizer_test.go +112 -0
  80. data/lib/helpers/fzf/src/tui/dummy.go +46 -0
  81. data/lib/helpers/fzf/src/tui/light.go +987 -0
  82. data/lib/helpers/fzf/src/tui/light_unix.go +110 -0
  83. data/lib/helpers/fzf/src/tui/light_windows.go +145 -0
  84. data/lib/helpers/fzf/src/tui/tcell.go +721 -0
  85. data/lib/helpers/fzf/src/tui/tcell_test.go +392 -0
  86. data/lib/helpers/fzf/src/tui/ttyname_unix.go +47 -0
  87. data/lib/helpers/fzf/src/tui/ttyname_windows.go +14 -0
  88. data/lib/helpers/fzf/src/tui/tui.go +625 -0
  89. data/lib/helpers/fzf/src/tui/tui_test.go +20 -0
  90. data/lib/helpers/fzf/src/util/atomicbool.go +34 -0
  91. data/lib/helpers/fzf/src/util/atomicbool_test.go +17 -0
  92. data/lib/helpers/fzf/src/util/chars.go +198 -0
  93. data/lib/helpers/fzf/src/util/chars_test.go +46 -0
  94. data/lib/helpers/fzf/src/util/eventbox.go +96 -0
  95. data/lib/helpers/fzf/src/util/eventbox_test.go +61 -0
  96. data/lib/helpers/fzf/src/util/slab.go +12 -0
  97. data/lib/helpers/fzf/src/util/util.go +138 -0
  98. data/lib/helpers/fzf/src/util/util_test.go +40 -0
  99. data/lib/helpers/fzf/src/util/util_unix.go +47 -0
  100. data/lib/helpers/fzf/src/util/util_windows.go +83 -0
  101. data/lib/helpers/fzf/test/fzf.vader +175 -0
  102. data/lib/helpers/fzf/test/test_go.rb +2626 -0
  103. data/lib/helpers/fzf/uninstall +117 -0
  104. data/scripts/generate_bash_completions.rb +6 -12
  105. data/scripts/generate_fish_completions.rb +7 -16
  106. data/scripts/generate_zsh_completions.rb +6 -15
  107. metadata +144 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cbd007c83df322397ff7da7025dfbc0e31fd0b54b3247bfffb2e7a61134366a5
4
- data.tar.gz: 78e741e12e3f28771d68bc7028caf2ed03edb677be1cfe8f975f32406d3d4f01
3
+ metadata.gz: 36dd66af3e00464697ab6eb89101e501e0b50ee6b21bc8629a13e21b3906c18a
4
+ data.tar.gz: 758903fc78fd9a812ab723a5af00cdec0c6cd13c1316dc638e9ca10f24bf939a
5
5
  SHA512:
6
- metadata.gz: 1a7262555d07ecea5e0e504df1edaacd48654156a50dff44f1d5ee365c04b6c5ae5f4785d9a97f7b6363c450d8184f186aff21ac47653684494e5aec3d1e5f8a
7
- data.tar.gz: 1b2e38445ffbe3a6a9687bdd8607f5b41591a4370e4ac68f4036155baceac97e98a50c58cb31e1948f6bdbfd6419fa419e9e1db75170e339227e09361f0b601b
6
+ metadata.gz: e755266bcfedb72b69f966a2621af76b5014168cd44898c2ba24b0dfc711482aef6a3694afd8010abbeb3bdeb88749532b15f1699ab6926227679ffb7308758d
7
+ data.tar.gz: f892efc03f34754866f436603e49c3e3f9b9ec52496ecdcddb1c5783abc485b7996bb5385d531a5814a4ee9b52d262f754545ee4a0a0559e49ccfff56de38bdb
data/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ ### 2.0.22
2
+
3
+ #### IMPROVED
4
+
5
+ - include fzf source directly, in case git isn't installed
6
+
7
+ ### 2.0.20
8
+
9
+ #### IMPROVED
10
+
11
+ - completion script generator refactor and progress bars
12
+
13
+ #### FIXED
14
+
15
+ - compile fzf for current operating system
16
+
17
+ ### 2.0.19
18
+
19
+ #### FIXED
20
+
21
+ - Remove any coloring before writing to doing file
22
+
1
23
  ### 2.0.18
2
24
 
3
25
  #### FIXED
data/Gemfile.lock CHANGED
@@ -1,12 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- doing (2.0.18)
4
+ doing (2.0.22)
5
5
  chronic (~> 0.10, >= 0.10.2)
6
6
  deep_merge (~> 1.2, >= 1.2.1)
7
7
  gli (~> 2.19, >= 2.19.2)
8
8
  haml (~> 5.0.0, >= 5.0.0)
9
9
  safe_yaml (~> 1.0)
10
+ tty-progressbar (~> 0.18, >= 0.18.2)
10
11
 
11
12
  GEM
12
13
  remote: http://rubygems.org/
@@ -89,6 +90,7 @@ GEM
89
90
  rspec-support (~> 3.10.0)
90
91
  rspec-support (3.10.3)
91
92
  safe_yaml (1.0.5)
93
+ strings-ansi (0.2.0)
92
94
  sys-uname (1.2.2)
93
95
  ffi (~> 1.1)
94
96
  temple (0.8.2)
@@ -97,8 +99,16 @@ GEM
97
99
  thor (1.1.0)
98
100
  thread_safe (0.3.6)
99
101
  tilt (2.0.10)
102
+ tty-cursor (0.7.1)
103
+ tty-progressbar (0.18.2)
104
+ strings-ansi (~> 0.2)
105
+ tty-cursor (~> 0.7)
106
+ tty-screen (~> 0.8)
107
+ unicode-display_width (>= 1.6, < 3.0)
108
+ tty-screen (0.8.1)
100
109
  tzinfo (2.0.4)
101
110
  concurrent-ruby (~> 1.0)
111
+ unicode-display_width (2.1.0)
102
112
  yard (0.9.26)
103
113
  zeitwerk (2.5.1)
104
114
 
@@ -108,13 +118,13 @@ PLATFORMS
108
118
  DEPENDENCIES
109
119
  aruba (~> 1.0.2)
110
120
  doing!
111
- github-markup
112
- parallel_tests
121
+ github-markup (~> 4.0, >= 4.0.0)
122
+ parallel_tests (~> 3.7, >= 3.7.3)
113
123
  rake (~> 13.0, >= 13.0.1)
114
124
  rdoc (~> 6.3.1)
115
- redcarpet
125
+ redcarpet (~> 3.5, >= 3.5.1)
116
126
  test-unit (~> 3.4.4)
117
- yard
127
+ yard (~> 0.9, >= 0.9.26)
118
128
 
119
129
  BUNDLED WITH
120
130
  2.2.17
data/README.md CHANGED
@@ -6,7 +6,7 @@ _If you're one of the rare people like me who find this useful, feel free to [bu
6
6
 
7
7
  <!--README-->
8
8
 
9
- The current version of `doing` is <!--VER-->2.0.17<!--END VER-->.
9
+ The current version of `doing` is <!--VER-->2.0.21<!--END VER-->.
10
10
 
11
11
  Find all of the documentation in the [doing wiki](https://github.com/ttscoff/doing/wiki).
12
12
 
data/bin/doing CHANGED
@@ -2149,28 +2149,12 @@ command :completion do |c|
2149
2149
 
2150
2150
  c.desc 'File to write output to'
2151
2151
  c.arg_name 'PATH'
2152
- c.flag %i[f file], default_value: 'stdout'
2152
+ c.flag %i[f file], default_value: 'STDOUT'
2153
2153
 
2154
2154
  c.action do |_global_options, options, _args|
2155
2155
  script_dir = File.join(File.dirname(__FILE__), '..', 'scripts')
2156
2156
 
2157
- case options[:type]
2158
- when /^b/
2159
- result = `ruby #{File.join(script_dir, 'generate_bash_completions.rb')}`
2160
- when /^z/
2161
- result = `ruby #{File.join(script_dir, 'generate_zsh_completions.rb')}`
2162
- when /^f/
2163
- result = `ruby #{File.join(script_dir, 'generate_fish_completions.rb')}`
2164
- end
2165
-
2166
- if options[:file] =~ /^stdout$/i
2167
- $stdout.puts result
2168
- else
2169
- File.open(File.expand_path(options[:file]), 'w') do |f|
2170
- f.puts result
2171
- end
2172
- Doing.logger.warn('File written:', "#{options[:type]} completions written to #{options[:file]}")
2173
- end
2157
+ Doing::Completion.generate_completion(type: options[:type], file: options[:file])
2174
2158
  end
2175
2159
  end
2176
2160
 
data/doing.gemspec CHANGED
@@ -27,10 +27,11 @@ spec = Gem::Specification.new do |s|
27
27
  s.add_development_dependency 'rdoc', '~> 6.3.1'
28
28
  s.add_development_dependency 'aruba', '~> 1.0.2'
29
29
  s.add_development_dependency 'test-unit', '~> 3.4.4'
30
- s.add_development_dependency 'yard'
31
- s.add_development_dependency 'redcarpet'
32
- s.add_development_dependency 'github-markup'
33
- s.add_development_dependency 'parallel_tests'
30
+ s.add_development_dependency 'yard', '~> 0.9', '>= 0.9.26'
31
+ s.add_development_dependency 'redcarpet', '~> 3.5', '>= 3.5.1'
32
+ s.add_development_dependency 'github-markup', '~> 4.0', '>= 4.0.0'
33
+ s.add_development_dependency 'parallel_tests', '~> 3.7', '>= 3.7.3'
34
+ s.add_runtime_dependency('tty-progressbar', '~> 0.18', '>= 0.18.2')
34
35
  s.add_runtime_dependency('gli', '~> 2.19', '>= 2.19.2')
35
36
  s.add_runtime_dependency('haml','~>5.0.0', '>= 5.0.0')
36
37
  s.add_runtime_dependency('chronic','~> 0.10', '>= 0.10.2')
data/doing.rdoc CHANGED
@@ -5,7 +5,7 @@ record of what you've been doing, complete with tag-based time tracking. The
5
5
  command line tool allows you to add entries, annotate with tags and notes, and
6
6
  view your entries with myriad options, with a focus on a "natural" language syntax.
7
7
 
8
- v2.0.18
8
+ v2.0.22
9
9
 
10
10
  === Global Options
11
11
  === --config_file arg
@@ -374,7 +374,7 @@ Generate shell completion scripts
374
374
 
375
375
  File to write output to
376
376
 
377
- [Default Value] stdout
377
+ [Default Value] STDOUT
378
378
 
379
379
 
380
380
  ===== -t|--type SHELL
@@ -1,5 +1,5 @@
1
1
  #!/bin/bash
2
2
 
3
- scripts/generate_fish_completions.rb > lib/completion/doing.fish
4
- scripts/generate_bash_completions.rb > lib/completion/doing.bash
5
- scripts/generate_zsh_completions.rb > lib/completion/_doing.zsh
3
+ bundle exec bin/doing completion --type fish --file lib/completion/doing.fish
4
+ bundle exec bin/doing completion --type bash --file lib/completion/doing.bash
5
+ bundle exec bin/doing completion --type zsh --file lib/completion/_doing.zsh
@@ -14,8 +14,12 @@ module Status
14
14
  $stderr.print format("#{esc['kill']}#{esc['boldyellow']}> #{esc['boldgreen']}%s #{esc['white']}[#{esc['boldwhite']}%#{@commands.count.to_s.length}d#{esc['boldblack']}/#{esc['boldyellow']}%d#{esc['white']}]: #{esc['boldcyan']}%s#{esc['default']}\r", msg, idx, total, tail)
15
15
  end
16
16
 
17
- def status(msg, reset: true)
18
- $stderr.print format("#{esc['kill']}#{esc['boldyellow']}> #{esc['whiteboard']}%s#{esc['default']}%s", msg, reset ? "\r" : "\n")
17
+ def status(msg, reset: true, end_char: "\n")
18
+ $stderr.print format("#{esc['kill']}#{esc['boldyellow']}> #{esc['whiteboard']}%s#{esc['default']}%s", msg, reset ? "\r" : end_char)
19
+ end
20
+
21
+ def msg(msg, reset: true, color: 'green', end_char: "\n")
22
+ $stderr.print format("#{esc['kill']}#{esc[color]}%s#{esc['default']}%s", msg, reset ? "\r" : end_char)
19
23
  end
20
24
 
21
25
  def clear
@@ -0,0 +1,185 @@
1
+ module Doing
2
+ module Completion
3
+ class BashCompletions
4
+ attr_accessor :commands, :global_options
5
+
6
+ def main_function
7
+ first = true
8
+ out = []
9
+ logic = []
10
+ need_export = []
11
+
12
+ @commands.each_with_index do |cmd, i|
13
+ @bar.advance
14
+
15
+ data = get_help_sections(cmd[:commands].first)
16
+
17
+ arg = data[:synopsis].join(' ').strip.split(/ /).last
18
+ case arg
19
+ when /(path|file)/i
20
+ type = :file
21
+ when /sect/i
22
+ type = 'sections'
23
+ when /view/i
24
+ type = 'views'
25
+ else
26
+ type = nil
27
+ end
28
+
29
+ if data[:command_options]
30
+ options = parse_options(data[:command_options])
31
+ out << command_function(cmd[:commands].first, options, type)
32
+
33
+ if first
34
+ op = 'if'
35
+ first = false
36
+ else
37
+ op = 'elif'
38
+ end
39
+ logic << %(#{op} [[ $last =~ (#{cmd[:commands].join('|')}) ]]; then _doing_#{cmd[:commands].first})
40
+ end
41
+ end
42
+
43
+ out << <<~EOFUNC
44
+ _doing()
45
+ {
46
+ local last="${@: -1}"
47
+ local token=${COMP_WORDS[$COMP_CWORD]}
48
+
49
+ #{logic.join("\n ")}
50
+ else
51
+ OLD_IFS="$IFS"
52
+ IFS=$'\n'
53
+ COMPREPLY=( $(compgen -W "$(doing help -c)" -- $token) )
54
+ IFS="$OLD_IFS"
55
+ fi
56
+ }
57
+ EOFUNC
58
+ out.join("\n")
59
+ end
60
+
61
+ def command_function(command, options, type)
62
+ long_options = []
63
+ short_options = []
64
+
65
+ options.each do |o|
66
+ next if o.nil?
67
+
68
+ long_options << o[:long] if o[:long]
69
+ short_options << o[:short] if o[:short]
70
+ end
71
+
72
+ long = long_options.map! {|o| "--#{o}"}.join(' ')
73
+ short = short_options.map! {|o| "-#{o}"}.join(' ')
74
+ words = ''
75
+ logic = ''
76
+ words, logic = get_words(type) if type && type.is_a?(String)
77
+
78
+ func = <<~ENDFUNC
79
+ _doing_#{command}() {
80
+ #{words}
81
+ if [[ "$token" == --* ]]; then
82
+ COMPREPLY=( $( compgen -W '#{long}' -- $token ) )
83
+ elif [[ "$token" == -* ]]; then
84
+ COMPREPLY=( $( compgen -W '#{short} #{long}' -- $token ) )
85
+ #{logic}
86
+ fi
87
+ }
88
+ ENDFUNC
89
+
90
+ func
91
+ end
92
+
93
+ def get_words(type)
94
+ func = <<~EOFUNC
95
+ OLD_IFS="$IFS"
96
+ local token=${COMP_WORDS[$COMP_CWORD]}
97
+ IFS=$'\t'
98
+ local words=$(doing #{type})
99
+ IFS="$OLD_IFS"
100
+ EOFUNC
101
+
102
+ logic = <<~EOLOGIC
103
+ else
104
+ local nocasematchWasOff=0
105
+ shopt nocasematch >/dev/null || nocasematchWasOff=1
106
+ (( nocasematchWasOff )) && shopt -s nocasematch
107
+ local w matches=()
108
+ OLD_IFS="$IFS"
109
+ IFS=$'\t'‰
110
+ for w in $words; do
111
+ if [[ "$w" == "$token"* ]]; then
112
+ matches+=("${w// /\ }")
113
+ fi
114
+ done
115
+ IFS="$OLD_IFS"
116
+ (( nocasematchWasOff )) && shopt -u nocasematch
117
+ COMPREPLY=("${matches[@]}")
118
+ EOLOGIC
119
+
120
+ [func, logic]
121
+ end
122
+
123
+
124
+
125
+ def get_help_sections(command = '')
126
+ res = `doing help #{command}`.strip
127
+ scanned = res.scan(/(?m-i)^([A-Z ]+)\n([\s\S]*?)(?=\n+[A-Z]+|\Z)/)
128
+ sections = {}
129
+ scanned.each do |sect|
130
+ title = sect[0].downcase.strip.gsub(/ +/, '_').to_sym
131
+ content = sect[1].split(/\n/).map(&:strip).delete_if(&:empty?)
132
+ sections[title] = content
133
+ end
134
+ sections
135
+ end
136
+
137
+ def parse_option(option)
138
+ res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>[\w_]+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
139
+ return nil unless res
140
+ {
141
+ short: res['short'],
142
+ long: res['long'],
143
+ arg: res[:arg],
144
+ description: res['desc'].short_desc
145
+ }
146
+ end
147
+
148
+ def parse_options(options)
149
+ options.map { |opt| parse_option(opt) }
150
+ end
151
+
152
+ def parse_command(command)
153
+ res = command.match(/^(?<cmd>[^, \t]+)(?<alias>(?:, [^, \t]+)*)?\s+- (?<desc>.*?)$/)
154
+ commands = [res['cmd']]
155
+ commands.concat(res['alias'].split(/, /).delete_if(&:empty?)) if res['alias']
156
+
157
+ {
158
+ commands: commands,
159
+ description: res['desc'].short_desc
160
+ }
161
+ end
162
+
163
+ def parse_commands(commands)
164
+ commands.map { |cmd| parse_command(cmd) }
165
+ end
166
+
167
+ def initialize
168
+ data = get_help_sections
169
+ @global_options = parse_options(data[:global_options])
170
+ @commands = parse_commands(data[:commands])
171
+ @bar = TTY::ProgressBar.new("\033[0;0;33mGenerating Bash completions: \033[0;35;40m[:bar]\033[0m", total: @commands.count, bar_format: :blade)
172
+ @bar.resize(25)
173
+ end
174
+
175
+ def generate_completions
176
+ @bar.start
177
+ out = []
178
+ out << main_function
179
+ out << 'complete -F _doing doing'
180
+ @bar.finish
181
+ out.join("\n")
182
+ end
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,175 @@
1
+ module Doing
2
+ module Completion
3
+ class FishCompletions
4
+
5
+ attr_accessor :commands, :global_options
6
+
7
+ def generate_helpers
8
+ <<~EOFUNCTIONS
9
+ function __fish_doing_needs_command
10
+ # Figure out if the current invocation already has a command.
11
+
12
+ set -l opts h-help config_file= f-doing_file= n-notes v-version stdout d-debug default x-noauto
13
+ set cmd (commandline -opc)
14
+ set -e cmd[1]
15
+ argparse -s $opts -- $cmd 2>/dev/null
16
+ or return 0
17
+ # These flags function as commands, effectively.
18
+ if set -q argv[1]
19
+ # Also print the command, so this can be used to figure out what it is.
20
+ echo $argv[1]
21
+ return 1
22
+ end
23
+ return 0
24
+ end
25
+
26
+ function __fish_doing_using_command
27
+ set -l cmd (__fish_doing_needs_command)
28
+ test -z "$cmd"
29
+ and return 1
30
+ contains -- $cmd $argv
31
+ and return 0
32
+ end
33
+
34
+ function __fish_doing_complete_sections
35
+ doing sections -c
36
+ end
37
+
38
+ function __fish_doing_complete_views
39
+ doing views -c
40
+ end
41
+
42
+ function __fish_doing_subcommands
43
+ doing help -c
44
+ end
45
+
46
+ function __fish_doing_export_plugins
47
+ doing plugins --type export -c
48
+ end
49
+
50
+ function __fish_doing_import_plugins
51
+ doing plugins --type import -c
52
+ end
53
+
54
+ function __fish_doing_complete_templates
55
+ doing template -c
56
+ end
57
+
58
+ complete -c doing -f
59
+ complete -xc doing -n '__fish_doing_needs_command' -a '(__fish_doing_subcommands)'
60
+
61
+ complete -f -c doing -n '__fish_doing_using_command show' -a '(__fish_doing_complete_sections)'
62
+ complete -f -c doing -n '__fish_doing_using_command view' -a '(__fish_doing_complete_views)'
63
+ complete -f -c doing -n '__fish_doing_using_command template' -a '(__fish_doing_complete_templates)'
64
+ complete -f -c doing -s t -l type -x -n '__fish_doing_using_command import' -a '(__fish_doing_import_plugins)'
65
+
66
+ complete -xc doing -n '__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from (doing help -c)' -a "(doing help -c)"
67
+ EOFUNCTIONS
68
+ end
69
+
70
+ def get_help_sections(command = '')
71
+ res = `doing help #{command}`.strip
72
+ scanned = res.scan(/(?m-i)^([A-Z ]+)\n([\s\S]*?)(?=\n+[A-Z]+|\Z)/)
73
+ sections = {}
74
+ scanned.each do |sect|
75
+ title = sect[0].downcase.strip.gsub(/ +/, '_').to_sym
76
+ content = sect[1].split(/\n/).map(&:strip).delete_if(&:empty?)
77
+ sections[title] = content
78
+ end
79
+ sections
80
+ end
81
+
82
+ def parse_option(option)
83
+ res = option.match(/(?:-(?<short>\w), )?(?:--(?:\[no-\])?(?<long>[\w_]+)(?:=(?<arg>\w+))?)\s+- (?<desc>.*?)$/)
84
+ return nil unless res
85
+ {
86
+ short: res['short'],
87
+ long: res['long'],
88
+ arg: res[:arg],
89
+ description: res['desc'].short_desc
90
+ }
91
+ end
92
+
93
+ def parse_options(options)
94
+ options.map { |opt| parse_option(opt) }
95
+ end
96
+
97
+ def parse_command(command)
98
+ res = command.match(/^(?<cmd>[^, \t]+)(?<alias>(?:, [^, \t]+)*)?\s+- (?<desc>.*?)$/)
99
+ commands = [res['cmd']]
100
+ commands.concat(res['alias'].split(/, /).delete_if(&:empty?)) if res['alias']
101
+
102
+ {
103
+ commands: commands,
104
+ description: res['desc'].short_desc
105
+ }
106
+ end
107
+
108
+ def parse_commands(commands)
109
+ commands.map { |cmd| parse_command(cmd) }
110
+ end
111
+
112
+ def generate_subcommand_completions
113
+ out = []
114
+ @commands.each_with_index do |cmd, i|
115
+ out << "complete -xc doing -n '__fish_doing_needs_command' -a '#{cmd[:commands].join(' ')}' -d #{Shellwords.escape(cmd[:description])}"
116
+ end
117
+
118
+ out.join("\n")
119
+ end
120
+
121
+ def generate_subcommand_option_completions
122
+
123
+ out = []
124
+ need_export = []
125
+
126
+ @commands.each_with_index do |cmd, i|
127
+ @bar.advance
128
+ data = get_help_sections(cmd[:commands].first)
129
+
130
+ if data[:synopsis].join(' ').strip.split(/ /).last =~ /(path|file)/i
131
+ out << "complete -c doing -F -n '__fish_doing_using_command #{cmd[:commands].join(" ")}'"
132
+ end
133
+
134
+ if data[:command_options]
135
+ parse_options(data[:command_options]).each do |option|
136
+ next if option.nil?
137
+
138
+ arg = option[:arg] ? '-r' : ''
139
+ short = option[:short] ? "-s #{option[:short]}" : ''
140
+ long = option[:long] ? "-l #{option[:long]}" : ''
141
+ out << "complete -c doing #{long} #{short} -f #{arg} -n '__fish_doing_using_command #{cmd[:commands].join(' ')}' -d #{Shellwords.escape(option[:description])}"
142
+
143
+ need_export.concat(cmd[:commands]) if option[:long] == 'output'
144
+ end
145
+ end
146
+ end
147
+
148
+ unless need_export.empty?
149
+ out << "complete -f -c doing -s o -l output -x -n '__fish_doing_using_command #{need_export.join(' ')}' -a '(__fish_doing_export_plugins)'"
150
+ end
151
+
152
+ # clear
153
+ out.join("\n")
154
+ end
155
+
156
+ def initialize
157
+ data = get_help_sections
158
+ @global_options = parse_options(data[:global_options])
159
+ @commands = parse_commands(data[:commands])
160
+ @bar = TTY::ProgressBar.new("\033[0;0;33mGenerating Fish completions: \033[0;35;40m[:bar]\033[0m", total: @commands.count, bar_format: :blade)
161
+ @bar.resize(25)
162
+ end
163
+
164
+ def generate_completions
165
+ @bar.start
166
+ out = []
167
+ out << generate_helpers
168
+ out << generate_subcommand_completions
169
+ out << generate_subcommand_option_completions
170
+ @bar.finish
171
+ out.join("\n")
172
+ end
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,17 @@
1
+ class ::String
2
+ def short_desc
3
+ split(/[,.]/)[0].sub(/ \(.*?\)?$/, '').strip
4
+ end
5
+
6
+ def ltrunc(max)
7
+ if length > max
8
+ sub(/^.*?(.{#{max - 3}})$/, '...\1')
9
+ else
10
+ self
11
+ end
12
+ end
13
+
14
+ def ltrunc!(max)
15
+ replace ltrunc(max)
16
+ end
17
+ end