Module: Howzit::Prompt
- Defined in:
- lib/howzit/prompt.rb
Overview
Command line prompt utils
Class Method Summary collapse
-
.choose(matches, height: :auto) ⇒ Array
Choose from a list of items.
-
.color_single_options(choices = %w[y n])) ⇒ String
Helper function to colorize the Y/N prompt.
- .fzf_options(height) ⇒ Object
- .fzf_result(res) ⇒ Object
-
.options_list(matches) ⇒ Object
Create a numbered list of options.
-
.read_editor(default = nil) ⇒ Object
Request editor.
-
.read_num(line) ⇒ Object
Convert a response to an Integer.
-
.read_selection(matches) ⇒ Object
Read a single number response from the command line.
-
.tty_menu(matches) ⇒ Object
Display a numeric menu on the TTY.
-
.yn(prompt, default: true) ⇒ Boolean
Display and read a Yes/No prompt.
Class Method Details
.choose(matches, height: :auto) ⇒ Array
Choose from a list of items. If fzf is available, uses that, otherwise generates its own list of options and accepts a numeric response
89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/howzit/prompt.rb', line 89 def choose(matches, height: :auto) return [] if !$stdout.isatty || matches.count.zero? if Util.command_exist?('fzf') height = height == :auto ? matches.count + 3 : TTY::Screen.rows settings = (height) res = `echo #{Shellwords.escape(matches.join("\n"))} | fzf #{settings.join(' ')}`.strip return fzf_result(res) end (matches) end |
.color_single_options(choices = %w[y n])) ⇒ String
Helper function to colorize the Y/N prompt
46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/howzit/prompt.rb', line 46 def (choices = %w[y n]) out = [] choices.each do |choice| case choice when /[A-Z]/ out.push(Color.template("{bw}#{choice}{x}")) else out.push(Color.template("{dw}#{choice}{xg}")) end end Color.template("{xg}[#{out.join('/')}{xg}]{x}") end |
.fzf_options(height) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/howzit/prompt.rb', line 111 def (height) [ '-0', '-1', '-m', "--height=#{height}", '--header="Tab: add selection, ctrl-a/d: (de)select all, return: display/run"', '--bind ctrl-a:select-all,ctrl-d:deselect-all,ctrl-t:toggle-all', '--prompt="Select a topic > "', %(--preview="howzit --no-pager --header-format block --no-color --default --multiple first {}") ] end |
.fzf_result(res) ⇒ Object
103 104 105 106 107 108 109 |
# File 'lib/howzit/prompt.rb', line 103 def fzf_result(res) if res.nil? || res.empty? Howzit.console.info 'Cancelled' Process.exit 0 end res.split(/\n/) end |
.options_list(matches) ⇒ Object
Create a numbered list of options. Outputs directly to console, returns nothing
65 66 67 68 69 70 71 72 73 |
# File 'lib/howzit/prompt.rb', line 65 def (matches) counter = 1 puts matches.each do |match| printf("%<counter>2d ) %<option>s\n", counter: counter, option: match) counter += 1 end puts end |
.read_editor(default = nil) ⇒ Object
Request editor
165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/howzit/prompt.rb', line 165 def read_editor(default = nil) @stty_save = `stty -g`.chomp default ||= 'vim' prompt = "Define a default editor command (default #{default}): " res = Readline.readline(prompt, true).squeeze(' ').strip res = default if res.empty? Util.valid_command?(res) ? res : default ensure system('stty', @stty_save) end |
.read_num(line) ⇒ Object
Convert a response to an Integer
183 184 185 186 187 188 189 |
# File 'lib/howzit/prompt.rb', line 183 def read_num(line) if line =~ /^[a-z]/i system('stty', @stty_save) # Restore exit end line == '' ? 1 : line.to_i end |
.read_selection(matches) ⇒ Object
Read a single number response from the command line
148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/howzit/prompt.rb', line 148 def read_selection(matches) printf "Type 'q' to cancel, enter for first item" while (line = Readline.readline(': ', true)) line = read_num(line) return [matches[line - 1]] if line.positive? && line <= matches.length puts 'Out of range' read_selection(matches) end ensure system('stty', @stty_save) end |
.tty_menu(matches) ⇒ Object
Display a numeric menu on the TTY
129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/howzit/prompt.rb', line 129 def (matches) return matches if matches.count == 1 @stty_save = `stty -g`.chomp trap('INT') do system('stty') exit end (matches) read_selection(matches) end |
.yn(prompt, default: true) ⇒ Boolean
Display and read a Yes/No prompt
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/howzit/prompt.rb', line 17 def yn(prompt, default: true) return default unless $stdout.isatty return true if Howzit.[:yes] return false if Howzit.[:no] return default if Howzit.[:default] tty_state = `stty -g` system 'stty raw -echo cbreak isig' yn = (default ? %w[Y n] : %w[y N]) $stdout.syswrite "\e[1;37m#{prompt} #{yn}\e[1;37m? \e[0m" res = $stdin.sysread 1 res.chomp! puts system 'stty cooked' system "stty #{tty_state}" res.empty? ? default : res =~ /y/i end |