todo-curses 0.0.3 → 0.0.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.
data/todo-curses.gemspec CHANGED
@@ -1,20 +1,27 @@
1
- # Ensure we require the local version and not one we might have installed already
2
- require File.join([File.dirname(__FILE__),'lib','todo','version.rb'])
3
- spec = Gem::Specification.new do |s|
4
- s.name = 'todo-curses'
5
- s.version = Todo::VERSION
6
- s.author = 'Loren Rogers'
7
- s.email = 'loren@lorentrogers.com'
8
- s.homepage = 'https://github.com/lorentrogers/todo-curses'
9
- s.platform = Gem::Platform::RUBY
10
- s.summary = 'An interactive terminal application for managing todo.txt files.'
11
- s.files = `git ls-files`.split("
12
- ")
13
- s.require_paths << 'lib'
14
- s.has_rdoc = true
15
- s.extra_rdoc_files = ['README.rdoc','todo.rdoc']
16
- s.rdoc_options << '--title' << 'todo-curses' << '--main' << 'README.rdoc' << '-ri'
17
- s.bindir = 'bin'
18
- s.executables << 'todo-curses'
19
- s.add_runtime_dependency('gli','2.13.4')
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'TodoCurses/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "todo-curses"
8
+ spec.license = "GPL-3.0"
9
+ spec.version = TodoCurses::VERSION
10
+ spec.authors = ["Loren Rogers"]
11
+ spec.email = ["loren@lorentrogers.com"]
12
+ spec.summary = %q{An interactive terminal application for managing todo.txt files.}
13
+ spec.homepage = "https://github.com/lorentrogers/todo-curses"
14
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
15
+ spec.bindir = "bin"
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_development_dependency "bundler", "~> 1.11"
20
+ spec.add_development_dependency "rake", "~> 10.0"
21
+ spec.add_development_dependency('rdoc', '~> 4.2', '>= 4.2.2')
22
+ spec.add_development_dependency('aruba', '~> 0.14.1')
23
+ spec.add_dependency('methadone', '~> 1.9', '>= 1.9.2')
24
+ spec.add_dependency('ncursesw', '~> 1.4', '>= 1.4.9')
25
+ spec.add_development_dependency('test-unit', '~> 3.1', '>= 3.1.8')
26
+ spec.add_development_dependency('rubocop', '~> 0.39.0')
20
27
  end
metadata CHANGED
@@ -1,74 +1,188 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: todo-curses
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Loren Rogers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-27 00:00:00.000000000 Z
11
+ date: 2016-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: gli
14
+ name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '='
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.13.4
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rdoc
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.2'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 4.2.2
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '4.2'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 4.2.2
61
+ - !ruby/object:Gem::Dependency
62
+ name: aruba
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 0.14.1
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 0.14.1
75
+ - !ruby/object:Gem::Dependency
76
+ name: methadone
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1.9'
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 1.9.2
20
85
  type: :runtime
21
86
  prerelease: false
22
87
  version_requirements: !ruby/object:Gem::Requirement
23
88
  requirements:
24
- - - '='
89
+ - - "~>"
25
90
  - !ruby/object:Gem::Version
26
- version: 2.13.4
91
+ version: '1.9'
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: 1.9.2
95
+ - !ruby/object:Gem::Dependency
96
+ name: ncursesw
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '1.4'
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: 1.4.9
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '1.4'
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: 1.4.9
115
+ - !ruby/object:Gem::Dependency
116
+ name: test-unit
117
+ requirement: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - "~>"
120
+ - !ruby/object:Gem::Version
121
+ version: '3.1'
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: 3.1.8
125
+ type: :development
126
+ prerelease: false
127
+ version_requirements: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '3.1'
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: 3.1.8
135
+ - !ruby/object:Gem::Dependency
136
+ name: rubocop
137
+ requirement: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - "~>"
140
+ - !ruby/object:Gem::Version
141
+ version: 0.39.0
142
+ type: :development
143
+ prerelease: false
144
+ version_requirements: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - "~>"
147
+ - !ruby/object:Gem::Version
148
+ version: 0.39.0
27
149
  description:
28
- email: loren@lorentrogers.com
150
+ email:
151
+ - loren@lorentrogers.com
29
152
  executables:
153
+ - console
154
+ - setup
30
155
  - todo-curses
31
156
  extensions: []
32
- extra_rdoc_files:
33
- - README.rdoc
34
- - todo.rdoc
157
+ extra_rdoc_files: []
35
158
  files:
36
159
  - ".gitignore"
160
+ - CONTRIBUTING.md
37
161
  - Gemfile
38
162
  - Gemfile.lock
39
163
  - LICENSE.txt
164
+ - README.md
40
165
  - README.rdoc
41
166
  - Rakefile
167
+ - bin/console
168
+ - bin/setup
42
169
  - bin/todo-curses
43
- - features/step_definitions/todo_steps.rb
44
- - features/support/env.rb
45
- - features/todo.feature
46
- - lib/todo-txt.rb
47
- - lib/todo-txt/list.rb
48
- - lib/todo-txt/logger.rb
49
- - lib/todo-txt/task.rb
50
- - lib/todo.rb
51
- - lib/todo/todo_viewer.rb
52
- - lib/todo/version.rb
53
- - reset.sh
54
- - run.sh
55
- - test/default_test.rb
56
- - test/test_helper.rb
170
+ - images/todo-curses-demo.gif
171
+ - lib/TodoCurses.rb
172
+ - lib/TodoCurses/list.rb
173
+ - lib/TodoCurses/logger.rb
174
+ - lib/TodoCurses/task.rb
175
+ - lib/TodoCurses/version.rb
176
+ - lib/TodoCurses/view.rb
57
177
  - todo-curses.gemspec
58
- - todo.rdoc
59
178
  homepage: https://github.com/lorentrogers/todo-curses
60
- licenses: []
179
+ licenses:
180
+ - GPL-3.0
61
181
  metadata: {}
62
182
  post_install_message:
63
- rdoc_options:
64
- - "--title"
65
- - todo-curses
66
- - "--main"
67
- - README.rdoc
68
- - "-ri"
183
+ rdoc_options: []
69
184
  require_paths:
70
185
  - lib
71
- - lib
72
186
  required_ruby_version: !ruby/object:Gem::Requirement
73
187
  requirements:
74
188
  - - ">="
@@ -1,6 +0,0 @@
1
- When /^I get help for "([^"]*)"$/ do |app_name|
2
- @app_name = app_name
3
- step %(I run `#{app_name} help`)
4
- end
5
-
6
- # Add more step definitions here
@@ -1,15 +0,0 @@
1
- require 'aruba/cucumber'
2
-
3
- ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
4
- LIB_DIR = File.join(File.expand_path(File.dirname(__FILE__)),'..','..','lib')
5
-
6
- Before do
7
- # Using "announce" causes massive warnings on 1.9.2
8
- @puts = true
9
- @original_rubylib = ENV['RUBYLIB']
10
- ENV['RUBYLIB'] = LIB_DIR + File::PATH_SEPARATOR + ENV['RUBYLIB'].to_s
11
- end
12
-
13
- After do
14
- ENV['RUBYLIB'] = @original_rubylib
15
- end
@@ -1,8 +0,0 @@
1
- Feature: My bootstrapped app kinda works
2
- In order to get going on coding my awesome app
3
- I want to have aruba and cucumber setup
4
- So I don't have to do it myself
5
-
6
- Scenario: App just runs
7
- When I get help for "todo"
8
- Then the exit status should be 0
data/lib/todo-txt.rb DELETED
@@ -1,7 +0,0 @@
1
- lib = File.dirname(__FILE__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
-
4
- require 'logger'
5
- require 'todo-txt/logger'
6
- require 'todo-txt/list'
7
- require 'todo-txt/task'
data/lib/todo.rb DELETED
@@ -1,6 +0,0 @@
1
- require 'gli'
2
- require 'todo-txt'
3
- require 'ncursesw'
4
- require 'todo/version.rb'
5
- require 'todo/todo_viewer.rb'
6
- require 'logger'
@@ -1,283 +0,0 @@
1
- # TODO: Refactor into proper size functions
2
- # A curses based todo.txt file viewer
3
- class TodoViewer
4
-
5
- # Run the ncurses application
6
- def interact
7
- while true
8
- result = true
9
- c = Ncurses.getch
10
- case c
11
- when 'J'.ord
12
- result = priority_down
13
- when 'K'.ord
14
- result = priority_up
15
- when 'x'.ord
16
- toggle_item_completion
17
- when 'n'.ord
18
- new_item
19
- when 'j'.ord
20
- result = scroll_down
21
- when 'k'.ord
22
- result = scroll_up
23
- # when '\s'.ord # white space
24
- # for i in 0..(@screen.getmaxy - 2)
25
- # if( ! scroll_down )
26
- # if( i == 0 )
27
- # result = false
28
- # end
29
- # break
30
- # end
31
- # end
32
- # when Ncurses::KEY_PPAGE
33
- # for i in 0..(@screen.getmaxy - 2)
34
- # if( ! scroll_up )
35
- # if( i == 0 )
36
- # result = false
37
- # end
38
- # break
39
- # end
40
- # end
41
- when 'h'.ord
42
- while( scroll_up )
43
- end
44
- when 'l'.ord
45
- while( scroll_down )
46
- end
47
- when 'q'.ord
48
- break
49
- else
50
- @screen.mvprintw(0,0, "[unknown key `#{Ncurses.keyname(c)}'=#{c}] ")
51
- end
52
- if( !result )
53
- Ncurses.beep
54
- end
55
- # TODO: Catch ctrl+c for graceful exit
56
- end
57
-
58
- # TODO: Confirm exit
59
- clean_done_tasks
60
- close_ncurses
61
- end
62
-
63
- private
64
-
65
- # Create a new fileviewer, and view the file.
66
- def initialize(filename)
67
- @log = Logger.new 'log.txt'
68
- @log.debug 'Run Started'
69
- init_curses
70
- load_file(filename)
71
- interact
72
- # TODO: Save a copy of the todo.txt list to backup file.
73
- end
74
-
75
- # Perform the curses setup
76
- def init_curses
77
- @screen = Ncurses.initscr
78
- Ncurses.nonl
79
- Ncurses.cbreak
80
- Ncurses.noecho
81
- @screen.scrollok(true)
82
- end
83
-
84
- # Loads the given file as a todo.txt array. Sets the view to the top
85
- # and redraws the list view.
86
- # @param filename [String] path to the text file to be loaded
87
- def load_file(filename)
88
- @done_file = File.dirname(filename) + '/done.txt'
89
- @list = Todo::List.new filename
90
- @list.sort! { |x,y| y <=> x } # Reverse sort
91
- items = []
92
- last_priority = nil
93
- last_selection = @menu.current_item.user_object if @menu
94
- current_selection = nil
95
-
96
- # Build the menu item list
97
- @list.each do |item|
98
- # Insert dividers on priority change
99
- if item.priority != last_priority
100
- divider_priority = item.priority.nil? ? 'N/A' : item.priority.to_s
101
- divider = Ncurses::Menu::ITEM.new(divider_priority, '')
102
- items << divider
103
- last_priority = item.priority
104
- end
105
-
106
- # Build the todo menu item
107
- menu_item = Ncurses::Menu::ITEM.new(item.to_s, '') # name, description
108
- menu_item.user_object = item
109
- items << menu_item
110
-
111
- # Set the current selection
112
- current_selection = menu_item if item.to_s == last_selection.to_s
113
- end
114
-
115
- # Build the final menu object
116
- # TODO: Possible memory leak from resetting object over top?
117
- @menu = Ncurses::Menu::MENU.new items
118
- @menu.set_menu_win(@screen)
119
- @menu.set_menu_sub(@screen.derwin(@screen.getmaxx, @screen.getmaxy, 0, 0))
120
- @menu.set_menu_format(@screen.getmaxy, 1)
121
-
122
- # Set dividers to non-interactive
123
- @menu.menu_items.select{ |i| i.user_object.nil? }.each do |divider|
124
- divider.item_opts_off Menu::O_SELECTABLE
125
- end
126
-
127
- # Show the menu
128
- @screen.clear
129
- @menu.post_menu
130
-
131
- # Set selection position
132
- @menu.set_current_item current_selection if current_selection
133
- @menu.menu_driver(Ncurses::Menu::REQ_DOWN_ITEM) if @menu.current_item.user_object.nil?
134
-
135
- # Refresh
136
- @screen.refresh
137
- end
138
-
139
- # Moves the current selection's priority up by one unless it is at Z.
140
- def priority_up
141
- item = @menu.current_item.user_object
142
- item.priority_inc
143
- save_list
144
- end
145
-
146
- # Moves the current selection's priority down by one unless it is at A.
147
- def priority_down
148
- item = @menu.current_item.user_object
149
- item.priority_dec
150
- save_list
151
- end
152
-
153
- # Scroll the display up by one line
154
- # @return [Boolean] true if the action completed successfully.
155
- def scroll_up
156
- # Move to the next item if it's not the first in the list
157
- unless @menu.menu_items[0].user_object.nil? &&
158
- @menu.current_item.item_index < 2
159
- result = @menu.menu_driver(Ncurses::Menu::REQ_UP_ITEM)
160
- end
161
- # Move to the next item if it's not a divider
162
- result = @menu.menu_driver(Ncurses::Menu::REQ_UP_ITEM) unless @menu.current_item.user_object
163
- return true if result == E_OK
164
- false
165
- end
166
-
167
- # Scroll the display down by one line
168
- # @return [Boolean] true if the action completed successfully.
169
- def scroll_down
170
- result = @menu.menu_driver(Ncurses::Menu::REQ_DOWN_ITEM)
171
- result = @menu.menu_driver(Ncurses::Menu::REQ_DOWN_ITEM) unless @menu.current_item.user_object
172
- return true if result == E_OK
173
- false
174
- end
175
-
176
- # Collects a new todo item from the user and saves
177
- # it to the text file.
178
- def new_item
179
- field = FIELD.new(1, @screen.getmaxx-1, 2, 1, 0, 0)
180
- field.set_field_back(A_UNDERLINE)
181
- fields = [field]
182
- my_form = FORM.new(fields);
183
- my_form.user_object = "My identifier"
184
-
185
- # Calculate the area required for the form
186
- rows = Array.new()
187
- cols = Array.new()
188
- my_form.scale_form(rows, cols);
189
-
190
- # Create the window to be associated with the form
191
- my_form_win = WINDOW.new(rows[0] + 3, cols[0] + 14, 1, 1);
192
- my_form_win.keypad(TRUE);
193
-
194
- # Set main window and sub window
195
- my_form.set_form_win(my_form_win);
196
- my_form.set_form_sub(my_form_win.derwin(rows[0], cols[0], 2, 12));
197
-
198
- my_form.post_form();
199
-
200
- # Print field types
201
- my_form_win.mvaddstr(4, 2, "New item")
202
- my_form_win.wrefresh();
203
-
204
- stdscr.refresh();
205
-
206
- new_item_text = capture_text_field_input(my_form_win, my_form, field)
207
-
208
- # Save results
209
- save_new_item(new_item_text)
210
-
211
- # Clean up
212
- my_form.unpost_form
213
- my_form.free_form
214
-
215
- field.free_field
216
- # fields.each {|f| f.free_field()}
217
- end
218
-
219
- # Adds a new item to the list and saves the file
220
- # @param task [String] the task to be added
221
- # @return [Todo::List] the updated list
222
- def save_new_item(task)
223
- @list << Todo::Task.new(task)
224
- save_list
225
- @list
226
- end
227
-
228
- # Saves the current state of the list. Overrides the current file.
229
- # Reloads the newly saved file.
230
- def save_list
231
- File.open(@list.path, 'w') { |file| file << @list.join("\n") }
232
- load_file @list.path
233
- end
234
-
235
- # Marks the currently selected menu item as complete and saves the list.
236
- def toggle_item_completion
237
- @menu.current_item.user_object.toggle!
238
- save_list
239
- end
240
-
241
- # Saves done tasks to done.txt and removes them from todo.txt
242
- def clean_done_tasks
243
- done_tasks = @list.select { |task| !task.completed_on.nil? }
244
- File.open(@done_file, 'a') { |file|
245
- file << "\n"
246
- file << done_tasks.join("\n")
247
- }
248
- remaining_tasks = @list.select { |task| task.completed_on.nil? }
249
- File.open(@list.path, 'w') { |file| file << remaining_tasks.join("\n") }
250
- end
251
-
252
- # put the screen back in its normal state
253
- def close_ncurses
254
- Ncurses.echo()
255
- Ncurses.nocbreak()
256
- Ncurses.nl()
257
- Ncurses.endwin()
258
- end
259
-
260
- # Captures text input into a form and returns the resulting string.
261
- # @param window [Window] the form window
262
- # @param form [FORM] the form to be captured
263
- # @param field [FIELD] the form to be captured
264
- # @return [String] the captured input
265
- def capture_text_field_input(window, form, field)
266
- # Capture typing...
267
- while((ch = window.getch()) != 13) # return is ascii 13
268
- case ch
269
- when KEY_LEFT
270
- form.form_driver(REQ_PREV_CHAR);
271
- when KEY_RIGHT
272
- form.form_driver(REQ_NEXT_CHAR);
273
- when KEY_BACKSPACE
274
- form.form_driver(REQ_DEL_PREV);
275
- else
276
- # If this is a normal character, it gets Printed
277
- form.form_driver(ch);
278
- end
279
- end
280
- form.form_driver REQ_NEXT_FIELD # Request next to set 0 buffer in field
281
- Ncurses::Form.field_buffer(field, 0)
282
- end
283
- end