na 1.2.28 → 1.2.30

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: a331d16e9572f0a63e251c2de46348880b73dbce47838968ac9ac987e6a053f5
4
- data.tar.gz: dec5319c89b04f65eb039867a5e01f6e1906c7287af2542bc7feab40f93dbf97
3
+ metadata.gz: 3d0dbc271a5a8f1812c5ef0596031d5ca9fc726efe0cde91e1172840d15acb61
4
+ data.tar.gz: 44599dadd458ebfcb610fcf80b5326231404f199f61b6e195b103bb4a095ff06
5
5
  SHA512:
6
- metadata.gz: 4ac0842dbf415b87ffa200662eea10ac9fd382406d2e953342f7c81777504e05710cf6bf622fc831309d58178c8d1622103713b82f81bfe5df07001366fb5058
7
- data.tar.gz: 975091dac71d91659df9c1c9b69722aad42cb74a69d6a030b7a2a335d0273925e72e87cce0afb9cc4507d7c5f376bf304a6f8a806dbeb25b7d03ff259e8031a1
6
+ metadata.gz: 448bea330450c05446027995d4ea6ccdb5cdf80fa43672d8ccb08a808ca9a171fbd80aa2d7e2054568c458411b25037db66b644e0bde43e8ac614b9b469d97cc
7
+ data.tar.gz: 146ed95b595f010a5964134f4eba2701ccd7a9b103c692941a8fb68052023f29b09ffabffba74dbc93a20a64397fe8417f9ab0343bde9a3af8d292bfa2351e6f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,33 @@
1
+ ### 1.2.30
2
+
3
+ 2023-08-29 06:50
4
+
5
+ #### NEW
6
+
7
+ - `na completed` to show completed actions with date ranges and search patterns
8
+ - Pagination using system pager
9
+
10
+ #### IMPROVED
11
+
12
+ - When replacing a priority tag, remove any space before it the action text
13
+ - Restore command decomposition
14
+ - Allow multiple saved searches to be executed at once
15
+ - `--restore` flag for update command to remove @done tags
16
+ - Pagination for help output
17
+
18
+ #### FIXED
19
+
20
+ - `--done` flag not working on `na next`
21
+ - Missing descriptions in help examples
22
+
23
+ ### 1.2.29
24
+
25
+ 2023-08-21 11:08
26
+
27
+ #### FIXED
28
+
29
+ - Reverting subcommand breakup
30
+
1
31
  ### 1.2.28
2
32
 
3
33
  2023-08-21 11:01
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- na (1.2.28)
4
+ na (1.2.30)
5
5
  chronic (~> 0.10, >= 0.10.2)
6
6
  gli (~> 2.21.0)
7
7
  mdless (~> 1.0, >= 1.0.32)
data/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  _If you're one of the rare people like me who find this useful, feel free to
10
10
  [buy me some coffee][donate]._
11
11
 
12
- The current version of `na` is 1.2.28
12
+ The current version of `na` is 1.2.30
13
13
  .
14
14
 
15
15
  `na` ("next action") is a command line tool designed to make it easy to see what your next actions are for any project, right from the command line. It works with TaskPaper-formatted files (but any plain text format will do), looking for `@na` tags (or whatever you specify) in todo files in your current folder.
@@ -77,42 +77,44 @@ SYNOPSIS
77
77
  na [global options] command [command options] [arguments...]
78
78
 
79
79
  VERSION
80
- 1.2.28
80
+ 1.2.30
81
81
 
82
82
  GLOBAL OPTIONS
83
83
  -a, --add - Add a next action (deprecated, for backwards compatibility)
84
84
  --add_at=POSITION - Add all new/moved entries at [s]tart or [e]nd of target project (default: start)
85
85
  --[no-]color - Colorize output (default: enabled)
86
86
  --cwd_as=TYPE - Use current working directory as [p]roject, [t]ag, or [n]one (default: none)
87
- -d, --depth=DEPTH - Recurse to depth (default: 3)
87
+ -d, --depth=DEPTH - Recurse to depth (default: 1)
88
88
  --[no-]debug - Display verbose output
89
89
  --ext=EXT - File extension to consider a todo file (default: taskpaper)
90
90
  -f, --file=PATH - Use a single file as global todo, use initconfig to make permanent (default: none)
91
91
  --help - Show this message
92
92
  -n, --note - Prompt for additional notes (deprecated, for backwards compatibility)
93
93
  -p, --priority=PRIORITY - Set a priority 0-5 (deprecated, for backwards compatibility) (default: none)
94
+ --[no-]pager - Enable pagination (default: enabled)
94
95
  -r, --[no-]recurse - Recurse 3 directories deep (deprecated, for backwards compatability)
95
96
  -t, --na_tag=TAG - Tag to consider a next action (default: na)
96
97
  --template=PATH - Provide a template for new/blank todo files, use initconfig to make permanent (default: none)
97
98
  --version - Display the program version
98
99
 
99
100
  COMMANDS
100
- add - Add a new next action
101
- archive - Mark an action as @done and archive
102
- changes, changelog - Display the changelog
103
- complete, finish - Find and mark an action as @done
104
- edit - Open a todo file in the default editor
105
- find, grep - Find actions matching a search pattern
106
- help - Shows a list of commands or help for one command
107
- init, create - Create a new todo file in the current directory
108
- initconfig - Initialize the config file using current global options
109
- next, show - Show next actions
110
- projects - Show list of projects for a file
111
- prompt - Show or install prompt hooks for the current shell
112
- saved - Execute a saved search
113
- tagged - Find actions matching a tag
114
- todos - Show list of known todo files
115
- update - Update an existing action
101
+ add - Add a new next action
102
+ archive - Mark an action as @done and archive
103
+ changes, changelog - Display the changelog
104
+ complete, finish - Find and mark an action as @done
105
+ completed, finished - Display completed actions
106
+ edit - Open a todo file in the default editor
107
+ find, grep - Find actions matching a search pattern
108
+ help - Shows a list of commands or help for one command
109
+ init, create - Create a new todo file in the current directory
110
+ initconfig - Initialize the config file using current global options
111
+ next, show - Show next actions
112
+ projects - Show list of projects for a file
113
+ prompt - Show or install prompt hooks for the current shell
114
+ saved - Execute a saved search
115
+ tagged - Find actions matching a tag
116
+ todos - Show list of known todo files
117
+ update - Update an existing action
116
118
  ```
117
119
 
118
120
  #### Commands
@@ -138,7 +140,7 @@ SYNOPSIS
138
140
  na [global options] add [command options] ACTION
139
141
 
140
142
  DESCRIPTION
141
- Provides an easy way to store todos while you work. Add quick reminders and (if you set up Prompt Hooks) they'll automatically display next time you enter the directory. If multiple todo files are found in the current directory, a menu will allow you to pick to which file the action gets added.
143
+ Provides an easy way to store todos while you work. Add quick reminders and (if you set up Prompt Hooks) they'll automatically display next time you enter the directory. If multiple todo files are found in the current directory, a menu will allow you to pick to which file the action gets added.
142
144
 
143
145
  COMMAND OPTIONS
144
146
  --at=POSITION - Add task at [s]tart or [e]nd of target project (default: none)
@@ -175,7 +177,7 @@ SYNOPSIS
175
177
  na [global options] edit [command options]
176
178
 
177
179
  DESCRIPTION
178
- Let the system choose the defualt, (e.g. TaskPaper), or specify a command line utility (e.g. vim). If more than one todo file is found, a menu is displayed.
180
+ Let the system choose the defualt, (e.g. TaskPaper), or specify a command line utility (e.g. vim). If more than one todo file is found, a menu is displayed.
179
181
 
180
182
  COMMAND OPTIONS
181
183
  -a, --app=EDITOR - Specify a Mac app (default: none)
@@ -188,7 +190,7 @@ EXAMPLES
188
190
  na edit
189
191
 
190
192
  # Display a menu of all todo files three levels deep from the
191
- current directory, open selection in vim.
193
+ current directory, open selection in vim.
192
194
  na edit -d 3 -a vim
193
195
  ```
194
196
 
@@ -207,7 +209,7 @@ SYNOPSIS
207
209
  na [global options] find [command options] PATTERN
208
210
 
209
211
  DESCRIPTION
210
- Search tokens are separated by spaces. Actions matching all tokens in the pattern will be shown (partial matches allowed). Add a + before a token to make it required, e.g. `na find +feature +maybe`, add a - or ! to ignore matches containing that token.
212
+ Search tokens are separated by spaces. Actions matching all tokens in the pattern will be shown (partial matches allowed). Add a + before a token to make it required, e.g. `na find +feature +maybe`, add a - or ! to ignore matches containing that token.
211
213
 
212
214
  COMMAND OPTIONS
213
215
  -d, --depth=DEPTH - Recurse to depth (default: none)
@@ -274,7 +276,7 @@ SYNOPSIS
274
276
  na [global options] next [command options] [QUERY]
275
277
 
276
278
  DESCRIPTION
277
- Next actions are actions which contain the next action tag (default @na), do not contain @done, and are not in the Archive project. Arguments will target a todo file from history, whether it's in the current directory or not. Todo file queries can include path components separated by / or :, and may use wildcards (`*` to match any text, `?` to match a single character). Multiple queries allowed (separate arguments or separated by comma).
279
+ Next actions are actions which contain the next action tag (default @na), do not contain @done, and are not in the Archive project. Arguments will target a todo file from history, whether it's in the current directory or not. Todo file queries can include path components separated by / or :, and may use wildcards (`*` to match any text, `?` to match a single character). Multiple queries allowed (separate arguments or separated by comma).
278
280
 
279
281
  COMMAND OPTIONS
280
282
  -d, --depth=DEPTH - Recurse to depth (default: none)
@@ -315,7 +317,7 @@ SYNOPSIS
315
317
  na [global options] projects [command options] [QUERY]
316
318
 
317
319
  DESCRIPTION
318
- Arguments will be interpreted as a query for a known todo file, fuzzy matched. Separate directories with /, :, or a space, e.g. `na projects code/marked`
320
+ Arguments will be interpreted as a query for a known todo file, fuzzy matched. Separate directories with /, :, or a space, e.g. `na projects code/marked`
319
321
 
320
322
  COMMAND OPTIONS
321
323
  -d, --depth=DEPTH - Search for files X directories deep (default: 1)
@@ -339,7 +341,7 @@ NAME
339
341
 
340
342
  SYNOPSIS
341
343
 
342
- na [global options] saved [command options] [SEARCH_TITLE]
344
+ na [global options] saved [command options] [SEARCH_TITLE]...
343
345
 
344
346
  DESCRIPTION
345
347
  Run without argument to list saved searches
@@ -350,14 +352,19 @@ COMMAND OPTIONS
350
352
 
351
353
  EXAMPLES
352
354
 
355
+ # save a search called "maybelater"
353
356
  na tagged "+maybe,+priority<=3" --save maybelater
354
357
 
358
+ # perform the search named "maybelater"
355
359
  na saved maybelater
356
360
 
361
+ # perform the search named "maybelater", assuming no other searches match "maybe"
357
362
  na saved maybe
358
363
 
364
+ # na run with no command and a single argument automatically performs a matching saved search
359
365
  na maybe
360
366
 
367
+ # list available searches
361
368
  na saved
362
369
  ```
363
370
 
@@ -380,7 +387,7 @@ SYNOPSIS
380
387
  na [global options] next [command options] [QUERY]
381
388
 
382
389
  DESCRIPTION
383
- Next actions are actions which contain the next action tag (default @na), do not contain @done, and are not in the Archive project. Arguments will target a todo file from history, whether it's in the current directory or not. Todo file queries can include path components separated by / or :, and may use wildcards (`*` to match any text, `?` to match a single character). Multiple queries allowed (separate arguments or separated by comma).
390
+ Next actions are actions which contain the next action tag (default @na), do not contain @done, and are not in the Archive project. Arguments will target a todo file from history, whether it's in the current directory or not. Todo file queries can include path components separated by / or :, and may use wildcards (`*` to match any text, `?` to match a single character). Multiple queries allowed (separate arguments or separated by comma).
384
391
 
385
392
  COMMAND OPTIONS
386
393
  -d, --depth=DEPTH - Recurse to depth (default: none)
@@ -421,7 +428,7 @@ SYNOPSIS
421
428
  na [global options] todos [QUERY]
422
429
 
423
430
  DESCRIPTION
424
- Arguments will be interpreted as a query against which the list of todos will be fuzzy matched. Separate directories with /, :, or a space, e.g. `na todos code/marked`
431
+ Arguments will be interpreted as a query against which the list of todos will be fuzzy matched. Separate directories with /, :, or a space, e.g. `na todos code/marked`
425
432
  ```
426
433
 
427
434
  ##### update
@@ -467,7 +474,7 @@ SYNOPSIS
467
474
  na [global options] update [command options] ACTION
468
475
 
469
476
  DESCRIPTION
470
- Provides an easy way to complete, prioritize, and tag existing actions. If multiple todo files are found in the current directory, a menu will allow you to pick which file to act on.
477
+ Provides an easy way to complete, prioritize, and tag existing actions. If multiple todo files are found in the current directory, a menu will allow you to pick which file to act on.
471
478
 
472
479
  COMMAND OPTIONS
473
480
  -a, --archive - Add a @done tag to action and move to Archive
@@ -480,10 +487,11 @@ COMMAND OPTIONS
480
487
  -f, --finish - Add a @done tag to action
481
488
  --file=PATH - Specify the file to search for the task (default: none)
482
489
  --in, --todo=TODO_FILE - Use a known todo file, partial matches allowed (default: none)
483
- -n, --note - Prompt for additional notes. Input will be appended to any existing note. If STDIN input (piped) is detected, it will be used as a note.
490
+ -n, --note - Prompt for additional notes. Input will be appended to any existing note. If STDIN input (piped) is detected, it will be used as a note.
484
491
  -o, --overwrite - Overwrite note instead of appending
485
492
  -p, --priority=PRIO - Add/change a priority level 1-5 (default: 0)
486
493
  -r, --remove=TAG - Remove a tag to the action (may be used more than once, default: none)
494
+ --restore - Remove @done tag from action
487
495
  -t, --tag=TAG - Add a tag to the action, @tag(values) allowed (may be used more than once, default: none)
488
496
  --tagged=TAG - Match actions containing tag. Allows value comparisons (may be used more than once, default: none)
489
497
  --to, --project, --proj=PROJECT - Move action to specific project (default: none)
data/bin/commands/add.rb CHANGED
@@ -1,183 +1,186 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- desc 'Add a new next action'
4
- long_desc 'Provides an easy way to store todos while you work. Add quick
5
- reminders and (if you set up Prompt Hooks) they\'ll automatically display
6
- next time you enter the directory.
7
-
8
- If multiple todo files are found in the current directory, a menu will
9
- allow you to pick to which file the action gets added.'
10
- arg_name 'ACTION'
11
- command :add do |c|
12
- c.example 'na add "A cool feature I thought of @idea"', desc: 'Add a new action to the Inbox, including a tag'
13
- c.example 'na add "A bug I need to fix" -p 4 -n',
14
- desc: 'Add a new action to the Inbox, set its @priority to 4, and prompt for an additional note.'
15
- c.example 'na add "An action item (with a note)"',
16
- desc: 'A parenthetical at the end of an action is interpreted as a note'
17
-
18
- c.desc 'Prompt for additional notes. STDIN input (piped) will be treated as a note if present.'
19
- c.switch %i[n note], negatable: false
20
-
21
- c.desc 'Add a priority level 1-5'
22
- c.arg_name 'PRIO'
23
- c.flag %i[p priority], must_match: /[1-5]/, type: :integer, default_value: 0
24
-
25
- c.desc 'Add action to specific project'
26
- c.arg_name 'PROJECT'
27
- c.default_value 'Inbox'
28
- c.flag %i[to project proj]
29
-
30
- c.desc 'Add task at [s]tart or [e]nd of target project'
31
- c.arg_name 'POSITION'
32
- c.flag %i[at], must_match: /^[sbea].*?$/i
33
-
34
- c.desc 'Add to a known todo file, partial matches allowed'
35
- c.arg_name 'TODO_FILE'
36
- c.flag %i[in todo]
37
-
38
- c.desc 'Use a tag other than the default next action tag'
39
- c.arg_name 'TAG'
40
- c.flag %i[t tag]
41
-
42
- c.desc 'Don\'t add next action tag to new entry'
43
- c.switch %i[x], negatable: false
44
-
45
- c.desc 'Specify the file to which the task should be added'
46
- c.arg_name 'PATH'
47
- c.flag %i[f file]
48
-
49
- c.desc 'Mark task as @done with date'
50
- c.switch %i[finish done], negatable: false
51
-
52
- c.desc 'Search for files X directories deep'
53
- c.arg_name 'DEPTH'
54
- c.flag %i[d depth], must_match: /^[1-9]$/, type: :integer, default_value: 1
55
-
56
- c.action do |global_options, options, args|
57
- reader = TTY::Reader.new
58
- append = options[:at] ? options[:at] =~ /^[ae]/i : global_options[:add_at] =~ /^[ae]/
59
-
60
- if NA.global_file
61
- target = File.expand_path(NA.global_file)
62
- unless File.exist?(target)
63
- res = NA.yn(NA::Color.template('{by}Specified file not found, create it'), default: true)
64
- if res
65
- basename = File.basename(target, ".#{NA.extension}")
66
- NA.create_todo(target, basename, template: global_options[:template])
67
- else
68
- puts NA::Color.template('{r}Cancelled{x}')
69
- Process.exit 1
70
- end
71
- end
72
- elsif options[:file]
73
- target = File.expand_path(options[:file])
74
- unless File.exist?(target)
75
- res = NA.yn(NA::Color.template('{by}Specified file not found, create it'), default: true)
76
- if res
77
- basename = File.basename(target, ".#{NA.extension}")
78
- NA.create_todo(target, basename, template: global_options[:template])
79
- else
80
- puts NA::Color.template('{r}Cancelled{x}')
81
- Process.exit 1
3
+ class App
4
+ extend GLI::App
5
+ desc 'Add a new next action'
6
+ long_desc 'Provides an easy way to store todos while you work. Add quick
7
+ reminders and (if you set up Prompt Hooks) they\'ll automatically display
8
+ next time you enter the directory.
9
+
10
+ If multiple todo files are found in the current directory, a menu will
11
+ allow you to pick to which file the action gets added.'
12
+ arg_name 'ACTION'
13
+ command :add do |c|
14
+ c.example 'na add "A cool feature I thought of @idea"', desc: 'Add a new action to the Inbox, including a tag'
15
+ c.example 'na add "A bug I need to fix" -p 4 -n',
16
+ desc: 'Add a new action to the Inbox, set its @priority to 4, and prompt for an additional note.'
17
+ c.example 'na add "An action item (with a note)"',
18
+ desc: 'A parenthetical at the end of an action is interpreted as a note'
19
+
20
+ c.desc 'Prompt for additional notes. STDIN input (piped) will be treated as a note if present.'
21
+ c.switch %i[n note], negatable: false
22
+
23
+ c.desc 'Add a priority level 1-5'
24
+ c.arg_name 'PRIO'
25
+ c.flag %i[p priority], must_match: /[1-5]/, type: :integer, default_value: 0
26
+
27
+ c.desc 'Add action to specific project'
28
+ c.arg_name 'PROJECT'
29
+ c.default_value 'Inbox'
30
+ c.flag %i[to project proj]
31
+
32
+ c.desc 'Add task at [s]tart or [e]nd of target project'
33
+ c.arg_name 'POSITION'
34
+ c.flag %i[at], must_match: /^[sbea].*?$/i
35
+
36
+ c.desc 'Add to a known todo file, partial matches allowed'
37
+ c.arg_name 'TODO_FILE'
38
+ c.flag %i[in todo]
39
+
40
+ c.desc 'Use a tag other than the default next action tag'
41
+ c.arg_name 'TAG'
42
+ c.flag %i[t tag]
43
+
44
+ c.desc 'Don\'t add next action tag to new entry'
45
+ c.switch %i[x], negatable: false
46
+
47
+ c.desc 'Specify the file to which the task should be added'
48
+ c.arg_name 'PATH'
49
+ c.flag %i[f file]
50
+
51
+ c.desc 'Mark task as @done with date'
52
+ c.switch %i[finish done], negatable: false
53
+
54
+ c.desc 'Search for files X directories deep'
55
+ c.arg_name 'DEPTH'
56
+ c.flag %i[d depth], must_match: /^[1-9]$/, type: :integer, default_value: 1
57
+
58
+ c.action do |global_options, options, args|
59
+ reader = TTY::Reader.new
60
+ append = options[:at] ? options[:at] =~ /^[ae]/i : global_options[:add_at] =~ /^[ae]/
61
+
62
+ if NA.global_file
63
+ target = File.expand_path(NA.global_file)
64
+ unless File.exist?(target)
65
+ res = NA.yn(NA::Color.template('{by}Specified file not found, create it'), default: true)
66
+ if res
67
+ basename = File.basename(target, ".#{NA.extension}")
68
+ NA.create_todo(target, basename, template: global_options[:template])
69
+ else
70
+ puts NA::Color.template('{r}Cancelled{x}')
71
+ Process.exit 1
72
+ end
82
73
  end
83
- end
84
- elsif options[:todo]
85
- todo = []
86
- all_req = options[:todo] !~ /[+!\-]/
87
- options[:todo].split(/ *, */).each do |a|
88
- m = a.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
89
- todo.push({
90
- token: m['tok'],
91
- required: all_req || (!m['req'].nil? && m['req'] == '+'),
92
- negate: !m['req'].nil? && m['req'] =~ /[!\-]/
93
- })
94
- end
95
- dirs = NA.match_working_dir(todo)
96
- if dirs.count.positive?
97
- target = dirs[0]
98
- else
99
- todo = "#{options[:todo].sub(/#{NA.extension}$/, '')}.#{NA.extension}"
100
- target = File.expand_path(todo)
74
+ elsif options[:file]
75
+ target = File.expand_path(options[:file])
101
76
  unless File.exist?(target)
77
+ res = NA.yn(NA::Color.template('{by}Specified file not found, create it'), default: true)
78
+ if res
79
+ basename = File.basename(target, ".#{NA.extension}")
80
+ NA.create_todo(target, basename, template: global_options[:template])
81
+ else
82
+ puts NA::Color.template('{r}Cancelled{x}')
83
+ Process.exit 1
84
+ end
85
+ end
86
+ elsif options[:todo]
87
+ todo = []
88
+ all_req = options[:todo] !~ /[+!\-]/
89
+ options[:todo].split(/ *, */).each do |a|
90
+ m = a.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
91
+ todo.push({
92
+ token: m['tok'],
93
+ required: all_req || (!m['req'].nil? && m['req'] == '+'),
94
+ negate: !m['req'].nil? && m['req'] =~ /[!\-]/
95
+ })
96
+ end
97
+ dirs = NA.match_working_dir(todo)
98
+ if dirs.count.positive?
99
+ target = dirs[0]
100
+ else
101
+ todo = "#{options[:todo].sub(/#{NA.extension}$/, '')}.#{NA.extension}"
102
+ target = File.expand_path(todo)
103
+ unless File.exist?(target)
102
104
 
103
- res = NA.yn(NA::Color.template("{by}Specified file not found, create #{todo}"), default: true)
104
- NA.notify('{r}Cancelled{x}', exit_code: 1) unless res
105
+ res = NA.yn(NA::Color.template("{by}Specified file not found, create #{todo}"), default: true)
106
+ NA.notify('{r}Cancelled{x}', exit_code: 1) unless res
105
107
 
106
- basename = File.basename(target, ".#{NA.extension}")
107
- NA.create_todo(target, basename, template: global_options[:template])
108
- end
108
+ basename = File.basename(target, ".#{NA.extension}")
109
+ NA.create_todo(target, basename, template: global_options[:template])
110
+ end
109
111
 
110
- end
111
- else
112
- files = NA.find_files(depth: options[:depth])
113
- if files.count.zero?
114
- res = NA.yn(NA::Color.template('{by}No todo file found, create one'), default: true)
115
- if res
116
- basename = File.expand_path('.').split('/').last
117
- target = "#{basename}.#{NA.extension}"
118
- NA.create_todo(target, basename, template: global_options[:template])
119
- files = NA.find_files(depth: 1)
120
112
  end
121
- end
122
- target = files.count > 1 ? NA.select_file(files) : files[0]
123
- NA.notify('{r}Cancelled{x}', exit_code: 1) unless files.count.positive? && File.exist?(target)
124
-
125
- end
113
+ else
114
+ files = NA.find_files(depth: options[:depth])
115
+ if files.count.zero?
116
+ res = NA.yn(NA::Color.template('{by}No todo file found, create one'), default: true)
117
+ if res
118
+ basename = File.expand_path('.').split('/').last
119
+ target = "#{basename}.#{NA.extension}"
120
+ NA.create_todo(target, basename, template: global_options[:template])
121
+ files = NA.find_files(depth: 1)
122
+ end
123
+ end
124
+ target = files.count > 1 ? NA.select_file(files) : files[0]
125
+ NA.notify('{r}Cancelled{x}', exit_code: 1) unless files.count.positive? && File.exist?(target)
126
126
 
127
- action = if args.count.positive?
128
- args.join(' ').strip
129
- elsif $stdin.isatty && TTY::Which.exist?('gum')
130
- `gum input --placeholder "Enter a task" --char-limit=500 --width=#{TTY::Screen.columns}`.strip
131
- elsif $stdin.isatty
132
- puts NA::Color.template('{bm}Enter task:{x}')
133
- reader.read_line(NA::Color.template('{by}> {bw}')).strip
134
- end
135
-
136
- if action.nil? || action.empty?
137
- puts 'Empty input, cancelled'
138
- Process.exit 1
139
- end
127
+ end
140
128
 
141
- if options[:priority]&.to_i&.positive?
142
- action = "#{action.gsub(/@priority\(\d+\)/, '')} @priority(#{options[:priority]})"
143
- end
129
+ action = if args.count.positive?
130
+ args.join(' ').strip
131
+ elsif $stdin.isatty && TTY::Which.exist?('gum')
132
+ `gum input --placeholder "Enter a task" --char-limit=500 --width=#{TTY::Screen.columns}`.strip
133
+ elsif $stdin.isatty
134
+ puts NA::Color.template('{bm}Enter task:{x}')
135
+ reader.read_line(NA::Color.template('{by}> {bw}')).strip
136
+ end
137
+
138
+ if action.nil? || action.empty?
139
+ puts 'Empty input, cancelled'
140
+ Process.exit 1
141
+ end
144
142
 
145
- note_rx = /^(.+) \((.*?)\)$/
146
- split_note = if action =~ note_rx
147
- n = Regexp.last_match(2)
148
- action.sub!(note_rx, '\1').strip!
149
- n
150
- end
151
-
152
- na_tag = NA.na_tag
153
- if options[:x]
154
- na_tag = ''
155
- else
156
- na_tag = options[:tag] unless options[:tag].nil?
157
- na_tag = " @#{na_tag}"
158
- end
143
+ if options[:priority]&.to_i&.positive?
144
+ action = "#{action.gsub(/@priority\(\d+\)/, '')} @priority(#{options[:priority]})"
145
+ end
159
146
 
160
- action = "#{action.gsub(/#{na_tag}\b/, '')}#{na_tag}"
147
+ note_rx = /^(.+) \((.*?)\)$/
148
+ split_note = if action =~ note_rx
149
+ n = Regexp.last_match(2)
150
+ action.sub!(note_rx, '\1').strip!
151
+ n
152
+ end
161
153
 
162
- stdin_note = NA.stdin ? NA.stdin.split("\n") : []
154
+ na_tag = NA.na_tag
155
+ if options[:x]
156
+ na_tag = ''
157
+ else
158
+ na_tag = options[:tag] unless options[:tag].nil?
159
+ na_tag = " @#{na_tag}"
160
+ end
163
161
 
164
- line_note = if options[:note] && $stdin.isatty
165
- puts stdin_note unless stdin_note.nil?
166
- if TTY::Which.exist?('gum')
167
- args = ['--placeholder "Enter additional note, CTRL-d to save"']
168
- args << '--char-limit 0'
169
- args << '--width $(tput cols)'
170
- `gum write #{args.join(' ')}`.strip.split("\n")
171
- else
172
- puts NA::Color.template('{bm}Enter a note, {bw}CTRL-d{bm} to end editing{bw}')
173
- reader.read_multiline
162
+ action = "#{action.gsub(/#{na_tag}\b/, '')}#{na_tag}"
163
+
164
+ stdin_note = NA.stdin ? NA.stdin.split("\n") : []
165
+
166
+ line_note = if options[:note] && $stdin.isatty
167
+ puts stdin_note unless stdin_note.nil?
168
+ if TTY::Which.exist?('gum')
169
+ args = ['--placeholder "Enter additional note, CTRL-d to save"']
170
+ args << '--char-limit 0'
171
+ args << '--width $(tput cols)'
172
+ `gum write #{args.join(' ')}`.strip.split("\n")
173
+ else
174
+ puts NA::Color.template('{bm}Enter a note, {bw}CTRL-d{bm} to end editing{bw}')
175
+ reader.read_multiline
176
+ end
174
177
  end
175
- end
176
178
 
177
- note = stdin_note.empty? ? [] : stdin_note
178
- note.concat(split_note) unless split_note.nil?
179
- note.concat(line_note) unless line_note.nil?
179
+ note = stdin_note.empty? ? [] : stdin_note
180
+ note.concat(split_note) unless split_note.nil?
181
+ note.concat(line_note) unless line_note.nil?
180
182
 
181
- NA.add_action(target, options[:project], action, note, finish: options[:finish], append: append)
183
+ NA.add_action(target, options[:project], action, note, finish: options[:finish], append: append)
184
+ end
182
185
  end
183
186
  end