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 +4 -4
- data/CHANGELOG.md +30 -0
- data/Gemfile.lock +1 -1
- data/README.md +38 -30
- data/bin/commands/add.rb +167 -164
- data/bin/commands/archive.rb +54 -51
- data/bin/commands/changes.rb +18 -15
- data/bin/commands/complete.rb +50 -47
- data/bin/commands/completed.rb +99 -0
- data/bin/commands/edit.rb +37 -34
- data/bin/commands/find.rb +109 -106
- data/bin/commands/init.rb +22 -19
- data/bin/commands/next.rb +135 -131
- data/bin/commands/projects.rb +27 -24
- data/bin/commands/prompt.rb +41 -38
- data/bin/commands/saved.rb +42 -34
- data/bin/commands/tagged.rb +137 -134
- data/bin/commands/todos.rb +23 -20
- data/bin/commands/update.rb +215 -207
- data/bin/na +12 -12
- data/lib/na/array.rb +13 -0
- data/lib/na/help_monkey_patch.rb +32 -0
- data/lib/na/next_action.rb +3 -2
- data/lib/na/pager.rb +94 -0
- data/lib/na/string.rb +10 -0
- data/lib/na/version.rb +1 -1
- data/lib/na.rb +2 -0
- data/src/_README.md +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d0dbc271a5a8f1812c5ef0596031d5ca9fc726efe0cde91e1172840d15acb61
|
4
|
+
data.tar.gz: 44599dadd458ebfcb610fcf80b5326231404f199f61b6e195b103bb4a095ff06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
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.
|
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.
|
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:
|
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
|
101
|
-
archive
|
102
|
-
changes, changelog
|
103
|
-
complete, finish
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
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
|
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).
|
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
|
-
|
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
|
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),
|
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,
|
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),
|
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
|
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.
|
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.
|
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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
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
|
-
|
84
|
-
|
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
|
-
|
104
|
-
|
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
|
-
|
107
|
-
|
108
|
-
|
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
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
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
|
-
|
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
|
-
|
142
|
-
|
143
|
-
|
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
|
-
|
146
|
-
|
147
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
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
|
-
|
178
|
-
|
179
|
-
|
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
|
-
|
183
|
+
NA.add_action(target, options[:project], action, note, finish: options[:finish], append: append)
|
184
|
+
end
|
182
185
|
end
|
183
186
|
end
|