menu_commander 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ac6321af9d45e46d217819d6659c88786ad23f6946d8c7f63076ed98ad8c3ba5
4
- data.tar.gz: 650c78d949042c8a3651edad05bc82491fcd7b7095fc4b638b4e52dcfe9b0b74
3
+ metadata.gz: fc729b17a7ba7e6fbba64302b2323cd073d9ea2a69b633f8ddbaf24890ff00a7
4
+ data.tar.gz: 82afd7ef1013dd8438b53da908a2841acf36a5bfe39148b7fd357e85a9548ef1
5
5
  SHA512:
6
- metadata.gz: d53c7fc17bd0ee211262624b0973d49eff0c433d5b819847989b211d452514e531d3183a662a9d1b878c916086a92b57ed3359d6b624a414cef470ee8f8410c2
7
- data.tar.gz: 446c8c2a2f6d99af790e1f011251a6005a83173aec102b2b6bf792bcce57bd9dd343a9d5488ce969da5a1f956203f22cf475a056234092b737786f6b32a3ef40
6
+ metadata.gz: 88bc9315c1c6502f1d3c40d12880a0b80e54bda56705fa00509a1b5aa6daacc398e67a4f241f0dbf45100dde6610803561842a58ed66ea440006a5cddbf27699
7
+ data.tar.gz: 85747cfd5579c748491c5526477b428b44c8458cb5cf6f8bbf29d0e05e06b4ed57bffc3616f21f50c286c3444c846a0e81e6bb0eb123de84d3c40339c4fb65ec
data/README.md CHANGED
@@ -14,14 +14,14 @@ Easily create menus for any command line tool using simple YAML configuration.
14
14
  * [Installation](#installation)
15
15
  * [Usage](#usage)
16
16
  * [Menu Navigation](#menu-navigation)
17
- * [Menu Configuration Features](#menu-configuration-features)
17
+ * [Menu Definition](#menu-definition)
18
18
  * [Minimal menu requirements](#minimal-menu-requirements)
19
19
  * [Argument sub-menus](#argument-sub-menus)
20
20
  * [Free text input](#free-text-input)
21
21
  * [Nested menus](#nested-menus)
22
- * [Header text](#header-text)
23
22
  * [Split menu into several files](#split-menu-into-several-files)
24
23
  * [Multi-line commands](#multi-line-commands)
24
+ * [Menu Options](#menu-options)
25
25
  * [Menu File Location](#menu-file-location)
26
26
 
27
27
  ---
@@ -81,7 +81,7 @@ $ menu some-other-file
81
81
 
82
82
 
83
83
 
84
- Menu Configuration Features
84
+ Menu Definition
85
85
  --------------------------------------------------
86
86
 
87
87
  All features have an example configuration in the
@@ -199,20 +199,6 @@ menu:
199
199
  > See: [examples/args-nested.yml](examples/args-nested.yml)
200
200
 
201
201
 
202
- ### Header text
203
-
204
- Use the `header` option to display a sentence or a multi-line paragraph when
205
- the menu is started. The header string supports [colsole color markers][1]:
206
-
207
- ```yaml
208
- header: |-
209
- Welcome to this !txtgrn!basic menu
210
- !bldred!Multiline!txtrst! headers are allowed
211
- ```
212
-
213
- > See: [examples/header.yml](examples/header.yml)
214
-
215
-
216
202
  ### Split menu into several files
217
203
 
218
204
  Each menu configuration file can include any number of additional YAML
@@ -276,6 +262,47 @@ menu:
276
262
  > See: [examples/multiline.yml](examples/multiline.yml)
277
263
 
278
264
 
265
+ Menu Options
266
+ --------------------------------------------------
267
+
268
+ You can tweak several aspects of the menu by adding an `options` section
269
+ in your YAML file.
270
+
271
+ ```yaml
272
+ options:
273
+ # Show header text
274
+ header: Hello
275
+
276
+ # Marker to show as the suffix of items that have submenus
277
+ # Use false to disable
278
+ submenu_marker: " ..."
279
+
280
+ # Menu selection marker
281
+ select_marker: ">"
282
+
283
+ # Menu title marker
284
+ title_marker: "-"
285
+
286
+ # When a menu has more items than page_size, add pagiation
287
+ # Default 10
288
+ page_size: 2
289
+
290
+ # When to show search filter
291
+ # yes = always show
292
+ # no = never show
293
+ # auto = show only when there aare more items than page_size (default)
294
+ # <number> = show only when there are more items than <number>
295
+ filter: yes
296
+
297
+ # When arg lists generate one item only it is auto-selected by default.
298
+ # Set this to false to disable this behavior
299
+ auto_select: false
300
+ ```
301
+
302
+ > See: [examples/optons.yml](examples/options.yml)
303
+
304
+
305
+
279
306
  Menu File Location
280
307
  --------------------------------------------------
281
308
 
data/bin/menu CHANGED
@@ -19,7 +19,7 @@ rescue MenuCommander::Exit => e
19
19
  rescue MenuCommander::MenuNotFound => e
20
20
  say! "#{e.message}"
21
21
  if e.paths and e.config
22
- message = "Looked for !txtgrn!#{e.config}.yml!txtrst! in"
22
+ message = "Looked for !txtgrn!#{e.config}!txtrst! in"
23
23
  if e.paths.size == 1
24
24
  message += " !txtgrn!#{e.paths.first}"
25
25
  say! message
@@ -4,24 +4,25 @@ module MenuCommander
4
4
  class Command < MisterBin::Command
5
5
  help "Menu Commander"
6
6
 
7
- usage "menu [CONFIG --dry --loop]"
7
+ usage "menu [CONFIG --loop (--dry|--confirm)]"
8
8
  usage "menu (-h|--help|--version)"
9
9
 
10
10
  option "-d --dry", "Dry run - do not execute the command at the end, just show it"
11
11
  option "-l --loop", "Reopen the menu after executing the selected command"
12
+ option "-c --confirm", "Show the command before execution and ask for confirmation"
12
13
  option "--version", "Show version number"
13
14
 
14
- param "CONFIG", "The name of the menu config file without the .yml extension [default: menu]"
15
+ param "CONFIG", "The name of the menu config file with or without the .yml extension [default: menu]"
15
16
 
16
17
  example "menu --dry"
17
- example "menu production --loop"
18
+ example "menu production --loop --confirm"
18
19
  example "menu -ld"
19
20
 
20
21
  attr_reader :last_command
21
22
 
22
23
  def run
23
24
  verify_sanity
24
- say "#{menu.header}\n" if menu.header
25
+ say "#{menu.options.header}\n" if menu.options.header
25
26
 
26
27
  if args['--loop']
27
28
  run_looped_menu
@@ -53,7 +54,10 @@ module MenuCommander
53
54
  command = menu.call
54
55
  @last_command = command
55
56
 
56
- if args['--dry']
57
+ if args['--confirm']
58
+ say "$ !txtpur!#{command}".strip
59
+ system command if prompt.yes? "Execute?"
60
+ elsif args['--dry']
57
61
  say "$ !txtpur!#{command}".strip
58
62
  else
59
63
  system command
@@ -66,7 +70,7 @@ module MenuCommander
66
70
 
67
71
  def menu_file!
68
72
  menu_paths.each do |dir|
69
- file = "#{dir}/#{config}.yml"
73
+ file = "#{dir}/#{config}"
70
74
  return file if File.exist? file
71
75
  end
72
76
  nil
@@ -81,7 +85,13 @@ module MenuCommander
81
85
  end
82
86
 
83
87
  def config
84
- config = args['CONFIG'] || 'menu'
88
+ result = args['CONFIG'] || 'menu'
89
+ result += ".yml" unless result.end_with?('.yml')
90
+ result
91
+ end
92
+
93
+ def prompt
94
+ @prompt ||= TTY::Prompt.new
85
95
  end
86
96
  end
87
97
  end
@@ -18,7 +18,7 @@ module MenuCommander
18
18
  class ExitMenu < Interrupt
19
19
  # :nocov:
20
20
  def initialize(message=nil)
21
- super (message || "> Exit")
21
+ super (message || "Goodbye")
22
22
  end
23
23
  # :nocov:
24
24
  end
@@ -24,8 +24,8 @@ module MenuCommander
24
24
 
25
25
  end
26
26
 
27
- def header
28
- config['header']
27
+ def options
28
+ @options ||= MenuOptions.new(config['options'])
29
29
  end
30
30
 
31
31
  private
@@ -70,9 +70,13 @@ module MenuCommander
70
70
  end
71
71
 
72
72
  def get_opts_type(opts)
73
- return :free_text if !opts
74
- return :static if opts.is_a? Array and opts.size == 1
75
- :menu
73
+ if !opts
74
+ :free_text
75
+ elsif options.auto_select and opts.is_a? Array and opts.size == 1
76
+ :static
77
+ else
78
+ :menu
79
+ end
76
80
  end
77
81
 
78
82
  def get_opts(key)
@@ -106,7 +110,6 @@ module MenuCommander
106
110
  end
107
111
  end
108
112
 
109
-
110
113
  def ask(title)
111
114
  prompt.ask "> #{title}:"
112
115
 
@@ -117,10 +120,36 @@ module MenuCommander
117
120
 
118
121
  end
119
122
 
120
- def select(options, title=nil)
121
- title = title ? "> #{title}:" : ">"
122
- enable_filter = options.size > 10
123
- prompt.select title, options, symbols: { marker: '>' }, per_page: 10, filter: enable_filter
123
+ def apply_suffix(choices)
124
+ choices.map do |key, value|
125
+ key = "#{key}#{options.submenu_marker}" if value.is_a? Hash
126
+ [key, value]
127
+ end.to_h
128
+ end
129
+
130
+ def enable_filter?(choices)
131
+ if options.filter === true
132
+ true
133
+ elsif options.filter === false
134
+ false
135
+ elsif options.filter.is_a? Numeric
136
+ choices.size > options.filter
137
+ else
138
+ choices.size > options.page_size
139
+ end
140
+ end
141
+
142
+ def select(choices, title=nil)
143
+ title = title ? "#{options.title_marker} #{title}:" : options.title_marker
144
+ choices = apply_suffix choices if options.submenu_marker
145
+ select! choices, title
146
+ end
147
+
148
+ def select!(choices, title)
149
+ prompt.select title, choices,
150
+ symbols: { marker: options.select_marker },
151
+ per_page: options.page_size,
152
+ filter: enable_filter?(choices)
124
153
 
125
154
  rescue TTY::Reader::InputInterrupt
126
155
  # :nocov:
@@ -0,0 +1,31 @@
1
+ module MenuCommander
2
+ class MenuOptions
3
+ attr_reader :options
4
+
5
+ def initialize(options)
6
+ options ||= {}
7
+ options.transform_keys! &:to_sym
8
+ @options = default_options.merge options
9
+ end
10
+
11
+ def default_options
12
+ @default_options ||= {
13
+ auto_select: true,
14
+ filter: 'auto',
15
+ header: false,
16
+ page_size: 10,
17
+ select_marker: "⯈",
18
+ submenu_marker: " ⯆",
19
+ title_marker: "◾",
20
+ }
21
+ end
22
+
23
+ def method_missing(method, *_args, &_block)
24
+ respond_to?(method) ? options[method] : super
25
+ end
26
+
27
+ def respond_to_missing?(method_name, include_private=false)
28
+ options.has_key?(method_name) || super
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ # :nocov:
2
+
3
+ # Required for Ruby < 2.5
4
+ if !{}.respond_to? :transform_keys!
5
+ class Hash
6
+ def transform_keys!
7
+ keys.each { |key| self[yield(key)] = delete(key) }
8
+ self
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,3 @@
1
1
  module MenuCommander
2
- VERSION = "0.1.6"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,4 +1,6 @@
1
+ require 'menu_commander/polyfills/hash'
1
2
  require 'menu_commander/exceptions'
3
+ require 'menu_commander/menu_options'
2
4
  require 'menu_commander/menu'
3
5
  require 'menu_commander/command'
4
6
  require 'menu_commander/cli'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: menu_commander
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-20 00:00:00.000000000 Z
11
+ date: 2019-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mister_bin
@@ -80,6 +80,8 @@ files:
80
80
  - lib/menu_commander/command.rb
81
81
  - lib/menu_commander/exceptions.rb
82
82
  - lib/menu_commander/menu.rb
83
+ - lib/menu_commander/menu_options.rb
84
+ - lib/menu_commander/polyfills/hash.rb
83
85
  - lib/menu_commander/version.rb
84
86
  homepage: https://github.com/dannyben/menu_commander
85
87
  licenses: