Class: Interactive
- Inherits:
-
Object
- Object
- Interactive
- Defined in:
- lib/interactive.rb
Constant Summary collapse
- KEY_TOP =
"\e[A"
- KEY_RIGHT =
"\e[C"
- KEY_DOWN =
"\e[B"
- KEY_LEFT =
"\e[D"
- KEY_BACKSPACE =
"\x7F"
- KEY_ENTER =
"\r"
- KEY_CTRL_C =
"\x03"
- KEY_TAB =
"\t"
- KEY_ESCAPE =
"\e"
- SEQ_ERASE_LEFT =
"\e[D"
- SEQ_ERASE_TO_END_OF_LINE =
"\033[K"
Instance Method Summary collapse
-
#initialize ⇒ Interactive
constructor
A new instance of Interactive.
- #interactive_edit(tasks) ⇒ Object
- #print_tasks ⇒ Object
- #read_char ⇒ Object
Constructor Details
#initialize ⇒ Interactive
Returns a new instance of Interactive.
15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/interactive.rb', line 15 def initialize @term_width = `/usr/bin/env tput cols`.to_i @formatter = TaskFormatter.new if @term_width < @formatter.max_width = " Your terminal must be at least #{@formatter.max_width} columns wide " STDERR.puts('<' + . rjust(@formatter.max_width + 1 - .length / 2, '-'). ljust(@formatter.max_width - 2, '-') + '>') exit(1) end end |
Instance Method Details
#interactive_edit(tasks) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/interactive.rb', line 78 def interactive_edit(tasks) @tasks = tasks @deleted_tasks = [] @header = '2015-06-03 ' + '[↑|↓] navigate, [⇽|⇾] adjust time, [⇐ ] remove, [↵ |q] save, [esc] cancel'.grey @task_selected = 0 loop do print_tasks input = read_char exit if [KEY_CTRL_C, KEY_ESCAPE].include? input return @deleted_tasks if [KEY_ENTER, 'q'].include? input top_down = { KEY_DOWN => +1, KEY_TOP => -1 } if top_down.keys.include? input @task_selected += top_down[input] @task_selected %= @tasks.length end left_right = { KEY_RIGHT => +300, KEY_LEFT => -300 } if left_right.keys.include? input time = @tasks[@task_selected].duration time = [time - (time % 300) + left_right[input], 0].max @tasks[@task_selected].duration = time @tasks[@task_selected].edited_at = Time.now end if input == KEY_BACKSPACE next if @tasks.length <= 1 @tasks[@task_selected].deleted_at = Time.now @deleted_tasks << @tasks[@task_selected] @tasks.delete_at(@task_selected) @task_selected -= 1 if @task_selected == @tasks.length @task_selected %= @tasks.length end end end |
#print_tasks ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/interactive.rb', line 56 def print_tasks task_len = TaskFormatter.max_length(@tasks) puts @header @tasks.each_with_index do |task, i| @formatter.format(task, task_len) print "\e[47m" + "\e[30m" if i == @task_selected print @formatter.line_for_interactive print "\e[0m" if i == @task_selected print ' ' + @formatter.sync_status print "\033[K" puts '' end total_time = Utils.format_time(@tasks.map(&:duration).reduce(:+)) puts "\e[100m #{''.ljust(task_len, ' ')} #{total_time} #{''.rjust(@formatter., ' ')} \e[0m\033[K" puts "\033[K" print "\033[#{@tasks.length + 3}A" end |
#read_char ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/interactive.rb', line 28 def read_char begin # save previous state of stty old_state = `stty -g` # disable echoing and enable raw (not having to press enter) system "stty raw -echo" c = STDIN.getc.chr # gather next two characters of special keys if (c=="\e") extra_thread = Thread.new { c = c + STDIN.getc.chr c = c + STDIN.getc.chr } # wait just long enough for special keys to get swallowed extra_thread.join(0.00001) # kill thread so not-so-long special keys don't wait on getc extra_thread.kill end rescue => ex puts "#{ex.class}: #{ex.}" puts ex.backtrace ensure # restore previous state of stty system "stty #{old_state}" end return c end |