todo-curses 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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