tabry 0.2.3 → 0.2.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 53cb186e419ee3ddbecddaf09ac32b39d93d5668c58fd81bc8d08ff16e1b168d
4
- data.tar.gz: c5d7fa4e944df15ff727eb0a9d38e2550da6988bdcf83f2dbaa743252f3c9669
3
+ metadata.gz: 87fa1708b1efb9ef81588017419bb6c63455ee786870f882783cf59f22ea462b
4
+ data.tar.gz: f0822419f2a36d48148cf7cf0ecdbd195666e2c5fe284d2e8dd6a563976c0842
5
5
  SHA512:
6
- metadata.gz: 1da3914992fd9ca409800f0183992fe6a742f0d55f04573e20c119cace1b00538294113c675a8281ff881703cbb13fb5a1802d4d164d9343dd4d5543cd9f2ca5
7
- data.tar.gz: 6a9797aaf76219131bcb3a6faa780ebedd0cd7971ad98f91e0d9f56d3d3302f4c29b62c9c4db0025fea4a1fea9047a40e54bf55400d2de1a7837915ddb7edc06
6
+ metadata.gz: de752dc58cefc4cc1caed94a4f0ae34758fdb40a9973f48ed5471b17fef517b0eecfbfd7e3735179793cce8d16d739d2cb2fe6d833c3f765f5c57e353dac1b7a
7
+ data.tar.gz: 3e26e31d951fbc7f076b3c6e5b2c96eccfd1287c5469f84447ec549dc6aca51746dc193cbed36276b2e81dab67ce2bee8204cc0e8bb6b4010a07b284bac75f32
data/bin/tabry-fish ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Run by the tabry_fish.sh fish tab completion function to plug into Tabry
5
+ # to get completion options.
6
+ # Fish-specific entrypoint
7
+
8
+ require_relative "../lib/tabry/shells/fish/wrapper"
9
+ Tabry::Fish::Wrapper.run(*ARGV)
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/tabry/cli/all_in_one"
4
+ require_relative "../lib/tabry/shells/fish"
5
+
6
+ Tabry::CLI::AllInOne.run do
7
+ config(names_underscores_to_dashes: true) do
8
+ desc <<~DESC
9
+ Generates fish completion for the tabry relative to this script
10
+ for the given command name and tabry JSON/YML file. Generates
11
+ fish functions unique to the command name to avoid conflicting with
12
+ other potential tabry installations.
13
+ DESC
14
+ arg :command_name, "Name of the command, e.g. 'mycli'"
15
+ arg :tabry_json_path, "Path to the mycli.json or mycli.yml compiled tabry file"
16
+ flagarg "uniq-fn-id,i", <<~DESC
17
+ Unique identifier to use for the unique tabry completion bash functions
18
+ (default is the capitalized command name)
19
+ DESC
20
+ end
21
+
22
+ def main
23
+ puts Tabry::Shells::Fish.generate(
24
+ args.command_name,
25
+ args.tabry_json_path,
26
+ uniq_fn_id: flags.uniq_fn_id,
27
+ )
28
+ end
29
+ end
30
+
31
+
@@ -25,7 +25,7 @@ module Tabry
25
25
 
26
26
  # Hack to avoid processing block any more if only running completion
27
27
  # That way you an have expensive requires after the include
28
- if (ARGV.first == "completion") && ARGV.length == 3 && ARGV[2].to_s =~ /^[0-9]+$/
28
+ if ((ARGV.first == "completion")) && ARGV.length == 3 && ARGV[2].to_s =~ /^[0-9]+$/
29
29
  throw :run_completion, true
30
30
  end
31
31
  end
@@ -45,14 +45,26 @@ module Tabry
45
45
 
46
46
  def self.define_completion_methods(cli_class, config, cmd_name: nil)
47
47
  cli_class.module_eval do
48
+
48
49
  define_method :completion__bash do
49
50
  require_relative "../shells/bash"
50
51
  Kernel.puts Tabry::Shells::Bash.generate_self(cmd_name: cmd_name)
51
52
  end
52
53
 
54
+ define_method :completion__fish do
55
+ require_relative "../shells/fish"
56
+ Kernel.puts Tabry::Shells::Fish.generate_self(cmd_name: cmd_name)
57
+ end
58
+
53
59
  define_method :completion do
54
- require_relative "../shells/bash/wrapper"
55
- Tabry::Bash::Wrapper.run(args.cmd_line, args.comp_point, config: config)
60
+ fish_mode = ENV.fetch("TABRY_FISH_MODE", false)
61
+ if fish_mode
62
+ require_relative "../shells/fish/wrapper"
63
+ Tabry::Fish::Wrapper.run(args.cmd_line, args.comp_point, config: config)
64
+ else
65
+ require_relative "../shells/bash/wrapper"
66
+ Tabry::Bash::Wrapper.run(args.cmd_line, args.comp_point, config: config)
67
+ end
56
68
  end
57
69
  end
58
70
  end
@@ -77,13 +89,22 @@ module Tabry
77
89
  # If we recognize command is going to be a completion command, fast track and
78
90
  # run completion now
79
91
  if run_completion
80
- require_relative "../shells/bash/wrapper"
81
- Tabry::Bash::Wrapper.run(ARGV[1], ARGV[2], config: config)
92
+ if ARGV.first == "completion"
93
+ fish_mode = ENV.fetch("TABRY_FISH_MODE", false)
94
+ if fish_mode
95
+ require_relative "../shells/fish/wrapper"
96
+ Tabry::Fish::Wrapper.run(ARGV[1], ARGV[2], config: config)
97
+ else
98
+ require_relative "../shells/bash/wrapper"
99
+ Tabry::Bash::Wrapper.run(ARGV[1], ARGV[2], config: config)
100
+ end
101
+ exit
102
+ end
82
103
  end
83
104
 
84
105
  # If we recognize there is a "completion" subcommand, add completion
85
106
  # methods -- if not already defined by caller in the block
86
- if config.main.subs.by_name["completion"] && !cli.instance_methods.include?(:completion__bash)
107
+ if config.main.subs.by_name["completion"] && !cli.instance_methods.include?(:completion__bash) && !cli.instance_methods.include?(:completion__fish)
87
108
  define_completion_methods(cli, config)
88
109
  end
89
110
 
@@ -24,6 +24,7 @@ module Tabry
24
24
  sub :completion do
25
25
  desc "Get tab completion shell config"
26
26
  sub :bash, "Get tab completion for bash or zsh"
27
+ sub :fish, "Get tab completion for fish"
27
28
  arg :cmd_line, "(for internal usage, when used instead of subcommand) full command line for getting completion options"
28
29
  arg :comp_point, "(for internal usage, when used instead of subcommand) comp point"
29
30
  end
@@ -5,7 +5,7 @@ require_relative "option_base"
5
5
  module Tabry
6
6
  module Models
7
7
  class ConstOption < OptionBase
8
- def options(token)
8
+ def options(token, _params)
9
9
  if value.start_with?(token)
10
10
  [value]
11
11
  else
@@ -16,10 +16,14 @@ module Tabry
16
16
  end
17
17
  end
18
18
 
19
- def options(token, used:)
19
+ def options(token, used:, params:)
20
20
  to_a.map do |flag|
21
21
  if token&.start_with?("-") && flag.name_with_dashes.start_with?(token) && !used[flag.name]
22
- flag.name_with_dashes
22
+ if params[:descriptions]
23
+ [flag.name_with_dashes, flag.description]
24
+ else
25
+ flag.name_with_dashes
26
+ end
23
27
  end
24
28
  end.compact
25
29
  end
@@ -7,8 +7,8 @@ module Tabry
7
7
  class IncludeOption < OptionBase
8
8
  attr_reader :include_name, :_root
9
9
 
10
- def options(token)
11
- flatten.options(token)
10
+ def options(token, params)
11
+ flatten.options(token, params)
12
12
  end
13
13
 
14
14
  def flatten
@@ -6,7 +6,7 @@ module Tabry
6
6
  module Models
7
7
  class MethodOption < OptionBase
8
8
  # TODO: Handled upstream for now, could change later.
9
- def options(_token)
9
+ def options(_token, _params)
10
10
  [value.to_sym]
11
11
  end
12
12
  end
@@ -10,8 +10,8 @@ module Tabry
10
10
  super(**args, klass: Option)
11
11
  end
12
12
 
13
- def options(token)
14
- to_a.map { |option| option.options(token) }.inject(&:|)
13
+ def options(token, params)
14
+ to_a.map { |option| option.options(token, params) }.inject(&:|)
15
15
  end
16
16
  end
17
17
  end
@@ -5,7 +5,7 @@ require_relative "option_base"
5
5
  module Tabry
6
6
  module Models
7
7
  class ShellOption < OptionBase
8
- def options(token)
8
+ def options(token, _params)
9
9
  `#{value}`.chomp.split("\n").select { |opt| opt.start_with?(token) }
10
10
  end
11
11
  end
@@ -20,9 +20,20 @@ module Tabry
20
20
  end
21
21
  end
22
22
 
23
- def options(token)
24
- to_a.map(&:name).select { |name| name.start_with?(token) }
23
+ def options(token, params)
24
+ ::Tabry::Util.debug "checking:::: #{token}"
25
+ to_a
26
+ .select { |sub| sub.name.start_with?(token) }
27
+ .map do |sub|
28
+ if params[:descriptions]
29
+ [sub.name, sub.description]
30
+ else
31
+ sub.name
32
+ end
33
+ end
34
+ .compact
25
35
  end
36
+
26
37
  end
27
38
  end
28
39
  end
@@ -4,15 +4,16 @@ require "json"
4
4
 
5
5
  module Tabry
6
6
  class OptionsFinder
7
- attr_reader :result
7
+ attr_reader :result, :params
8
8
 
9
9
  # Returns an array of options
10
- def self.options(result, token)
11
- new(result).options(token)
10
+ def self.options(result, token, params)
11
+ new(result, params).options(token)
12
12
  end
13
13
 
14
- def initialize(result)
14
+ def initialize(result, params)
15
15
  @result = result
16
+ @params = params
16
17
  end
17
18
 
18
19
  def options(token)
@@ -59,7 +60,7 @@ module Tabry
59
60
 
60
61
  def options_flagarg(token)
61
62
  result.sub_stack.map do |sub|
62
- sub.flags[state.current_flag]&.options&.options(token)
63
+ sub.flags[state.current_flag]&.options&.options(token, params)
63
64
  end.compact.flatten.uniq
64
65
  end
65
66
 
@@ -68,14 +69,18 @@ module Tabry
68
69
  # once an arg has been given, can no longer use a subcommand
69
70
  []
70
71
  else
71
- current_sub.subs.options(token)
72
+ current_sub.subs.options(token, params)
72
73
  end
73
74
  end
74
75
 
75
76
  def options_subcommand_flags(token)
76
77
  return [] if state.dashdash
77
78
 
78
- result.sub_stack.map { |sub| sub.flags.options(token, used: state.flags) }.flatten.uniq
79
+ result
80
+ .sub_stack
81
+ .map { |sub| sub.flags.options(token, used: state.flags, params: params) }
82
+ .flatten(1)
83
+ .uniq
79
84
  end
80
85
 
81
86
  def options_subcommand_args(token)
@@ -85,7 +90,7 @@ module Tabry
85
90
  current_sub.args[state.args.length]
86
91
  end
87
92
 
88
- arg&.options&.options(token) || []
93
+ arg&.options&.options(token, params) || []
89
94
  end
90
95
  end
91
96
  end
data/lib/tabry/runner.rb CHANGED
@@ -19,8 +19,8 @@ module Tabry
19
19
  end
20
20
  end
21
21
 
22
- def options(args, last = nil)
23
- Tabry::OptionsFinder.options(parse(args), last)
22
+ def options(args, last = nil, params = {})
23
+ Tabry::OptionsFinder.options(parse(args), last, params)
24
24
  end
25
25
 
26
26
  def parse(args)
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "shellwords"
4
+ require "yaml"
5
+ require_relative "../../util"
6
+ require_relative "../../runner"
7
+ require_relative "../../shell_tokenizer"
8
+
9
+ # Fish-specific entrypoint
10
+ module Tabry
11
+ module Fish
12
+ module Wrapper
13
+ DESCRIPTION_MAX_LENGTH = 50
14
+
15
+ def self.run(cmd_line, comp_point, config: nil)
16
+ cmd_name, args, last_arg = Tabry::ShellTokenizer.split_with_comppoint(cmd_line, comp_point)
17
+ opts = Tabry::Runner.new(config: config || cmd_name).options(args, last_arg, {descriptions: true})
18
+
19
+ if Tabry::Util.debug?
20
+ $stderr.puts
21
+ warn "debug: got command line and comp_point: #{cmd_line.inspect}, #{comp_point}"
22
+ warn "using args: #{args.inspect}"
23
+ warn "using lastarg: #{last_arg.inspect}"
24
+ warn "results from Tabry#options(): #{opts.inspect}"
25
+ warn "--- end debug output ---"
26
+ end
27
+
28
+ normal_opts = opts.select { |t,| t.is_a?(String) }
29
+ special_opts = opts.select { |t| t.is_a?(Symbol) }
30
+
31
+ puts normal_opts.map { |opt, desc| "#{Shellwords.escape(opt)}\t#{format_description(desc)}" }.join("\n")
32
+ if special_opts.any?
33
+ puts
34
+ puts special_opts.join("\n")
35
+ end
36
+ end
37
+
38
+ def self.format_description(description)
39
+ if description.nil?
40
+ ""
41
+ else
42
+ if description.length > DESCRIPTION_MAX_LENGTH
43
+ "#{description[0..(DESCRIPTION_MAX_LENGTH - 3)]}..."
44
+ else
45
+ description
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Used to generate a tab-completion function for a Tabry CLI using absolute
4
+ # paths to the tabry-bash script in this repo and to the Tabry JSON/YML file.
5
+ # Using uniquely-named tab-completion functions and absolute paths means you can
6
+ # have different Tabry-based CLIs using different versions of Tabry without any
7
+ # conflicts.
8
+ # See sh/bash/README.md and "Adding Tab Completion to your CLI" in main README
9
+
10
+ require "shellwords"
11
+
12
+ module Tabry
13
+ module Shells
14
+ module Fish
15
+ # NOTE! This code uses sh/fish/tabry_fish.fish and is described in
16
+ # sh/fish/README.md; see that README for more info
17
+ def self.generate(cmd_name, tabry_file_path, uniq_fn_id: nil)
18
+ generate_internal(
19
+ cmd_name: cmd_name,
20
+ import_path: File.expand_path(tabry_file_path),
21
+ tabry_fish_executable: File.expand_path("#{path_to_tabry}/bin/tabry-fish"),
22
+ tabry_fish_arg: nil,
23
+ uniq_fn_id: uniq_fn_id
24
+ )
25
+ end
26
+
27
+ # Generate fish completion code that will run the currently running
28
+ # command ($0) with "completion" to get completion options. "cmd_name"
29
+ # is used to tell fish which command to make options for
30
+ def self.generate_self(cmd_name: nil)
31
+ cmd_name ||= File.basename($0)
32
+ generate_internal(
33
+ cmd_name: cmd_name,
34
+ import_path: "",
35
+ tabry_fish_executable: File.expand_path($0),
36
+ tabry_fish_arg: "completion",
37
+ )
38
+ end
39
+
40
+ def self.path_to_tabry
41
+ File.expand_path("#{__dir__}/../../../")
42
+ end
43
+
44
+ def self.esc(s)
45
+ Shellwords.escape(s)
46
+ end
47
+
48
+ def self.add_uniq_id(str, pattern, uniq_id)
49
+ str.gsub! pattern, "#{pattern}_#{uniq_id}"
50
+ end
51
+
52
+ def self.generate_internal(cmd_name:, import_path:, tabry_fish_executable:, tabry_fish_arg:, uniq_fn_id: nil)
53
+ # uniq_fn_id is added to the bash functions to ensure they are unique
54
+ # -- by default this is the capitalized command name
55
+ uniq_fn_id ||= cmd_name
56
+ uniq_fn_id = uniq_fn_id.upcase.gsub(/[^A-Z0-9_]/, "_")
57
+ script = File.read("#{__dir__}/../../../sh/fish/tabry_fish.fish")
58
+
59
+ add_uniq_id(script, "tabry_completion_init", uniq_fn_id)
60
+ add_uniq_id(script, "__fish_tabry_internal_invoke", uniq_fn_id)
61
+ add_uniq_id(script, "__fish_tabry_check_only_args", uniq_fn_id)
62
+ add_uniq_id(script, "__fish_tabry_check_only_file", uniq_fn_id)
63
+ add_uniq_id(script, "__fish_tabry_check_args_and_file", uniq_fn_id)
64
+ add_uniq_id(script, "__fish_tabry_completions", uniq_fn_id)
65
+
66
+ script.gsub! "# TABRY_IMPORT_PATH_REPLACE (DO NOT REMOVE)", "set TABRY_IMPORTS_PATH #{esc import_path}"
67
+ script.gsub! "# TABRY_EXECUTABLE_REPLACE (DO NOT REMOVE)", "set TABRY_EXECUTABLE #{esc tabry_fish_executable}"
68
+ if !tabry_fish_arg.nil?
69
+ script.gsub! "# TABRY_ARG_REPLACE (DO NOT REMOVE)", "set TABRY_ARG #{esc tabry_fish_arg}"
70
+ end
71
+
72
+ <<~END_FISH_CODE_TEMPLATE
73
+ # The following Autocomplete is for a Tabry-powered command. It was
74
+ # generated by the command itself. See the documentation located in
75
+ # #{esc path_to_tabry}/sh/fish/README.md
76
+ #{script}
77
+ tabry_completion_init_#{uniq_fn_id} #{esc cmd_name}
78
+ END_FISH_CODE_TEMPLATE
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,3 @@
1
+ module Tabry
2
+ VERSION = "0.2.4"
3
+ end
data/sh/fish/README.md CHANGED
@@ -2,8 +2,9 @@ This directory includes fish completions for Tabry
2
2
 
3
3
  There are two steps to add to your ~/.config/fish/config.fish to use:
4
4
 
5
- 1. Source this file
5
+ 1. Source `tabry_fish.fish`
6
6
  2. Add a call to `tabry_completion_init`, for each command
7
+ 3. Ensure the `TABRY_IMPORTS_PATH` environment variable is defined and points to where your compiled tabry files are located.
7
8
 
8
9
  ```sh
9
10
  source tabry_fish.fish
@@ -12,14 +12,19 @@ end
12
12
 
13
13
  # return true if tabry only reports commands
14
14
  function __fish_tabry_internal_invoke
15
- set SCRIPT (status --current-filename)
16
- set SCRIPT_DIR (dirname $SCRIPT)
15
+ # TABRY_IMPORT_PATH_REPLACE (DO NOT REMOVE)
16
+ # TABRY_EXECUTABLE_REPLACE (DO NOT REMOVE)
17
+ # TABRY_ARG_REPLACE (DO NOT REMOVE)
18
+ set -x TABRY_FISH_MODE true
17
19
 
18
20
  # -C "Get cursor position"
19
21
  set cursor_position (commandline -C)
20
22
  set cmd (commandline)
21
- set result ($SCRIPT_DIR/../../bin/tabry-bash "$cmd" "$cursor_position")
22
- echo $result
23
+
24
+ set result ($TABRY_EXECUTABLE $TABRY_ARG "$cmd" "$cursor_position")
25
+ for arg in $result
26
+ echo $arg
27
+ end
23
28
  end
24
29
 
25
30
  # return true if tabry only reports file
@@ -75,16 +80,14 @@ function __fish_tabry_completions
75
80
 
76
81
  set args (echo "$result"|sed 's/ .*//')
77
82
 
78
- # The '--' arg is needed in case $result contains flag-like strings
79
- set args_parsed (string split -- ' ' $args)
80
-
81
83
  if test "x$args" = "x"
82
84
  # Don't offer anything if we don't have any completions
83
85
  return 1;
84
86
  else
85
- # $args_parsed will be something like: ["foo" "bar" "baz" "" "file"]
87
+ # $result will be something like: ["foo 'this is foo'" "bar" "baz" "" "file"]
86
88
  # where "file" is special, since it's after the space.
87
- for arg in $args_parsed
89
+ for arg in $result
90
+ set clean_arg (echo "$arg"|sed 's/ .*//')
88
91
  if test "x$arg" != "x"
89
92
  echo "$arg"
90
93
  else
@@ -3,6 +3,7 @@
3
3
  require_relative "../../../lib/tabry/cli/all_in_one"
4
4
  require_relative "../../../lib/tabry/shells/bash"
5
5
  require_relative "../../../lib/tabry/shells/bash/wrapper"
6
+ require_relative "../../../lib/tabry/shells/fish"
6
7
 
7
8
  module Tabry::Spec
8
9
  module Cli
@@ -124,6 +125,17 @@ describe Tabry::CLI::AllInOne do
124
125
  end
125
126
  end
126
127
 
128
+ it "creates a #completion__fish method which generates completion" do
129
+ stub_const("ARGV", %w[completion fish])
130
+ expect(Tabry::Shells::Fish).to receive(:generate_self).with(cmd_name: "foo").and_return("fish completion stuff")
131
+ expect_any_instance_of(Kernel).to receive(:puts).with("fish completion stuff")
132
+
133
+ described_class.completion_only do
134
+ cmd :foo
135
+ sub :bar
136
+ end
137
+ end
138
+
127
139
  it "creates a #completion method which generates options" do
128
140
  stub_const("ARGV", ["completion", "cmd line", "6"])
129
141
  expect(Tabry::Bash::Wrapper).to receive(:run) do |cmd_line, comp_point, config:|
data/tabry.gemspec CHANGED
@@ -1,12 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # TODO: these 2 lines are cargo cult
4
- lib = File.expand_path("lib", __dir__)
5
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require_relative './lib/tabry/version'
6
4
 
7
5
  Gem::Specification.new do |s|
8
6
  s.name = "tabry"
9
- s.version = "0.2.3"
7
+ s.version = Tabry::VERSION
10
8
  s.summary = "Tab completion and CLIs extraordinaire"
11
9
  s.authors = ["Evan Battaglia"]
12
10
  s.email = "battaglia.evan@gmail.com"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tabry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Battaglia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-23 00:00:00.000000000 Z
11
+ date: 2023-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry-byebug
@@ -84,7 +84,9 @@ description:
84
84
  email: battaglia.evan@gmail.com
85
85
  executables:
86
86
  - tabry-bash
87
+ - tabry-fish
87
88
  - tabry-generate-bash-complete
89
+ - tabry-generate-fish-complete
88
90
  - tabry-help
89
91
  - tabry-test-options
90
92
  - tabry-test-parse
@@ -92,7 +94,9 @@ extensions: []
92
94
  extra_rdoc_files: []
93
95
  files:
94
96
  - bin/tabry-bash
97
+ - bin/tabry-fish
95
98
  - bin/tabry-generate-bash-complete
99
+ - bin/tabry-generate-fish-complete
96
100
  - bin/tabry-help
97
101
  - bin/tabry-test-options
98
102
  - bin/tabry-test-parse
@@ -148,9 +152,12 @@ files:
148
152
  - lib/tabry/shell_tokenizer.rb
149
153
  - lib/tabry/shells/bash.rb
150
154
  - lib/tabry/shells/bash/wrapper.rb
155
+ - lib/tabry/shells/fish.rb
156
+ - lib/tabry/shells/fish/wrapper.rb
151
157
  - lib/tabry/state.rb
152
158
  - lib/tabry/usage_generator.rb
153
159
  - lib/tabry/util.rb
160
+ - lib/tabry/version.rb
154
161
  - sh/bash/README.md
155
162
  - sh/bash/tabry_bash.sh
156
163
  - sh/bash/tabry_bash_core.sh