na 1.2.45 → 1.2.47
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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +26 -0
- data/Gemfile.lock +1 -1
- data/README.md +50 -42
- data/bin/commands/archive.rb +19 -2
- data/bin/commands/complete.rb +13 -2
- data/bin/commands/update.rb +26 -7
- data/lib/na/action.rb +21 -9
- data/lib/na/actions.rb +1 -1
- data/lib/na/array.rb +7 -0
- data/lib/na/next_action.rb +28 -22
- data/lib/na/todo.rb +1 -3
- data/lib/na/version.rb +1 -1
- data/src/_README.md +1 -1
- metadata +1 -2
- data/test2.txt +0 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ed76ea2928d227d65651ad179f0950c2505611c540673f96494feae0ce621ca1
|
|
4
|
+
data.tar.gz: da06581a2771d1675ef1e69229803de2a677b6e30b5a4e2531e8497677cfe40a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 63e8b9f8fdd3ad3c394dbe022030ab334f3826dbba22d7a0d6971ab02a7d47db243cc308517825a84589bae8ea4333d9aceb393640dd4f13d4d6e67f7a5fa0ef
|
|
7
|
+
data.tar.gz: 4145b57e31f6f876c965b540adf187584e91acb8f2438b9eef8fced56c2938a2c7dd004f7c65a5a5b9040bfd2fc55675e1fc18a579c1318d17f7efe3a80a70b5
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
### 1.2.47
|
|
2
|
+
|
|
3
|
+
2023-09-07 10:47
|
|
4
|
+
|
|
5
|
+
#### NEW
|
|
6
|
+
|
|
7
|
+
- `na update --search OLD_TEXT --replace NEW_TEXT` (added --replace)
|
|
8
|
+
|
|
9
|
+
#### IMPROVED
|
|
10
|
+
|
|
11
|
+
- When not showing notes, add an asterisk in the template note
|
|
12
|
+
- When showing notes, indent to the beginning of the action
|
|
13
|
+
|
|
14
|
+
### 1.2.46
|
|
15
|
+
|
|
16
|
+
2023-09-06 21:25
|
|
17
|
+
|
|
18
|
+
#### IMPROVED
|
|
19
|
+
|
|
20
|
+
- Add `--project` to archive and update
|
|
21
|
+
- Add `--project` flag to complete
|
|
22
|
+
|
|
23
|
+
#### FIXED
|
|
24
|
+
|
|
25
|
+
- Error when creating new project in todo file
|
|
26
|
+
|
|
1
27
|
### 1.2.45
|
|
2
28
|
|
|
3
29
|
2023-09-06 19:19
|
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.47
|
|
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,7 +77,7 @@ SYNOPSIS
|
|
|
77
77
|
na [global options] command [command options] [arguments...]
|
|
78
78
|
|
|
79
79
|
VERSION
|
|
80
|
-
1.2.
|
|
80
|
+
1.2.47
|
|
81
81
|
|
|
82
82
|
GLOBAL OPTIONS
|
|
83
83
|
-a, --add - Add a next action (deprecated, for backwards compatibility)
|
|
@@ -487,26 +487,29 @@ DESCRIPTION
|
|
|
487
487
|
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.
|
|
488
488
|
|
|
489
489
|
COMMAND OPTIONS
|
|
490
|
-
-a, --archive
|
|
491
|
-
--all
|
|
492
|
-
--at=POSITION
|
|
493
|
-
-d, --depth=DEPTH
|
|
494
|
-
--delete
|
|
495
|
-
--[no-]done
|
|
496
|
-
-e, --regex
|
|
497
|
-
--edit
|
|
498
|
-
-f, --finish
|
|
499
|
-
--file=PATH
|
|
500
|
-
--in, --todo=TODO_FILE
|
|
501
|
-
-n, --note
|
|
502
|
-
-o, --overwrite
|
|
503
|
-
-p, --priority=PRIO
|
|
504
|
-
|
|
505
|
-
--
|
|
506
|
-
|
|
507
|
-
--
|
|
508
|
-
--
|
|
509
|
-
-
|
|
490
|
+
-a, --archive - Add a @done tag to action and move to Archive
|
|
491
|
+
--all - Act on all matches immediately (no menu)
|
|
492
|
+
--at=POSITION - When moving task, add at [s]tart or [e]nd of target project (default: none)
|
|
493
|
+
-d, --depth=DEPTH - Search for files X directories deep (default: 1)
|
|
494
|
+
--delete - Delete an action
|
|
495
|
+
--[no-]done - Include @done actions
|
|
496
|
+
-e, --regex - Interpret search pattern as regular expression
|
|
497
|
+
--edit - Open action in editor (vim). Natural language dates will be parsed and converted in date-based tags.
|
|
498
|
+
-f, --finish - Add a @done tag to action
|
|
499
|
+
--file=PATH - Specify the file to search for the task (default: none)
|
|
500
|
+
--in, --todo=TODO_FILE - Use a known todo file, partial matches allowed (default: none)
|
|
501
|
+
-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.
|
|
502
|
+
-o, --overwrite - Overwrite note instead of appending
|
|
503
|
+
-p, --priority=PRIO - Add/change a priority level 1-5 (default: 0)
|
|
504
|
+
--proj, --project=PROJECT[/SUBPROJECT] - Affect actions from a specific project (default: none)
|
|
505
|
+
-r, --remove=TAG - Remove a tag from the action, use multiple times or combine multiple tags with a comma, wildcards (* and ?) allowed (may be used more than once, default: none)
|
|
506
|
+
--replace=TEXT - Use with --find to find and replace with new text. Enables --exact when used (default: none)
|
|
507
|
+
--restore - Remove @done tag from action
|
|
508
|
+
--search, --find, --grep=QUERY - Filter results using search terms (may be used more than once, default: none)
|
|
509
|
+
-t, --tag=TAG - Add a tag to the action, @tag(values) allowed, use multiple times or combine multiple tags with a comma (may be used more than once, default: none)
|
|
510
|
+
--tagged=TAG - Match actions containing tag. Allows value comparisons (may be used more than once, default: none)
|
|
511
|
+
--to, --move=PROJECT - Move action to specific project (default: none)
|
|
512
|
+
-x, --exact - Match pattern exactly
|
|
510
513
|
|
|
511
514
|
EXAMPLES
|
|
512
515
|
|
|
@@ -546,17 +549,19 @@ SYNOPSIS
|
|
|
546
549
|
na [global options] complete [command options] ACTION
|
|
547
550
|
|
|
548
551
|
COMMAND OPTIONS
|
|
549
|
-
-a, --archive
|
|
550
|
-
--all
|
|
551
|
-
-d, --depth=DEPTH
|
|
552
|
-
-e, --regex
|
|
553
|
-
--file=PATH
|
|
554
|
-
--in, --todo=TODO_FILE
|
|
555
|
-
-n, --note
|
|
556
|
-
-o, --overwrite
|
|
557
|
-
--
|
|
558
|
-
--
|
|
559
|
-
|
|
552
|
+
-a, --archive - Add a @done tag to action and move to Archive
|
|
553
|
+
--all - Act on all matches immediately (no menu)
|
|
554
|
+
-d, --depth=DEPTH - Search for files X directories deep (default: 1)
|
|
555
|
+
-e, --regex - Interpret search pattern as regular expression
|
|
556
|
+
--file=PATH - Specify the file to search for the task (default: none)
|
|
557
|
+
--in, --todo=TODO_FILE - Use a known todo file, partial matches allowed (default: none)
|
|
558
|
+
-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.
|
|
559
|
+
-o, --overwrite - Overwrite note instead of appending
|
|
560
|
+
--proj, --project=PROJECT[/SUBPROJECT] - Affect actions from a specific project (default: none)
|
|
561
|
+
--search, --find, --grep=QUERY - Filter results using search terms (may be used more than once, default: none)
|
|
562
|
+
--tagged=TAG - Match actions containing tag. Allows value comparisons (may be used more than once, default: none)
|
|
563
|
+
--to, --move=PROJECT - Move action to specific project (default: none)
|
|
564
|
+
-x, --exact - Match pattern exactly
|
|
560
565
|
|
|
561
566
|
EXAMPLES
|
|
562
567
|
|
|
@@ -580,15 +585,18 @@ SYNOPSIS
|
|
|
580
585
|
na [global options] archive [command options] ACTION
|
|
581
586
|
|
|
582
587
|
COMMAND OPTIONS
|
|
583
|
-
--all
|
|
584
|
-
-d, --depth=DEPTH
|
|
585
|
-
--done
|
|
586
|
-
-e, --regex
|
|
587
|
-
--file=PATH
|
|
588
|
-
|
|
589
|
-
-
|
|
590
|
-
--
|
|
591
|
-
|
|
588
|
+
--all - Act on all matches immediately (no menu)
|
|
589
|
+
-d, --depth=DEPTH - Search for files X directories deep (default: 1)
|
|
590
|
+
--done - Archive all done tasks
|
|
591
|
+
-e, --regex - Interpret search pattern as regular expression
|
|
592
|
+
--file=PATH - Specify the file to search for the task (default: none)
|
|
593
|
+
--in, --todo=TODO_FILE - Use a known todo file, partial matches allowed (default: none)
|
|
594
|
+
-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.
|
|
595
|
+
-o, --overwrite - Overwrite note instead of appending
|
|
596
|
+
--proj, --project=PROJECT[/SUBPROJECT] - Affect actions from a specific project (default: none)
|
|
597
|
+
--search, --find, --grep=QUERY - Filter results using search terms (may be used more than once, default: none)
|
|
598
|
+
--tagged=TAG - Match actions containing tag. Allows value comparisons (may be used more than once, default: none)
|
|
599
|
+
-x, --exact - Match pattern exactly
|
|
592
600
|
|
|
593
601
|
EXAMPLE
|
|
594
602
|
|
data/bin/commands/archive.rb
CHANGED
|
@@ -30,24 +30,41 @@ class App
|
|
|
30
30
|
c.arg_name 'TAG'
|
|
31
31
|
c.flag %i[tagged], multiple: true
|
|
32
32
|
|
|
33
|
+
c.desc 'Affect actions from a specific project'
|
|
34
|
+
c.arg_name 'PROJECT[/SUBPROJECT]'
|
|
35
|
+
c.flag %i[proj project]
|
|
36
|
+
|
|
33
37
|
c.desc 'Act on all matches immediately (no menu)'
|
|
34
38
|
c.switch %i[all], negatable: false
|
|
35
39
|
|
|
40
|
+
c.desc 'Filter results using search terms'
|
|
41
|
+
c.arg_name 'QUERY'
|
|
42
|
+
c.flag %i[search find grep], multiple: true
|
|
43
|
+
|
|
36
44
|
c.desc 'Interpret search pattern as regular expression'
|
|
37
45
|
c.switch %i[e regex], negatable: false
|
|
38
46
|
|
|
39
47
|
c.desc 'Match pattern exactly'
|
|
40
48
|
c.switch %i[x exact], negatable: false
|
|
41
49
|
|
|
50
|
+
c.desc 'Use a known todo file, partial matches allowed'
|
|
51
|
+
c.arg_name 'TODO_FILE'
|
|
52
|
+
c.flag %i[in todo]
|
|
53
|
+
|
|
42
54
|
c.action do |global, options, args|
|
|
55
|
+
args.concat(options[:search])
|
|
56
|
+
|
|
43
57
|
if options[:done]
|
|
44
|
-
options[:tagged]
|
|
58
|
+
options[:tagged] << 'done'
|
|
45
59
|
options[:all] = true
|
|
60
|
+
else
|
|
61
|
+
options[:tagged] << '-done'
|
|
46
62
|
end
|
|
47
63
|
|
|
48
64
|
options[:done] = true
|
|
65
|
+
options['done'] = true
|
|
49
66
|
options[:finish] = true
|
|
50
|
-
options[:
|
|
67
|
+
options[:move] = 'Archive'
|
|
51
68
|
options[:archive] = true
|
|
52
69
|
options[:a] = true
|
|
53
70
|
|
data/bin/commands/complete.rb
CHANGED
|
@@ -22,7 +22,11 @@ class App
|
|
|
22
22
|
|
|
23
23
|
c.desc 'Move action to specific project'
|
|
24
24
|
c.arg_name 'PROJECT'
|
|
25
|
-
c.flag %i[to
|
|
25
|
+
c.flag %i[to move]
|
|
26
|
+
|
|
27
|
+
c.desc 'Affect actions from a specific project'
|
|
28
|
+
c.arg_name 'PROJECT[/SUBPROJECT]'
|
|
29
|
+
c.flag %i[proj project]
|
|
26
30
|
|
|
27
31
|
c.desc 'Specify the file to search for the task'
|
|
28
32
|
c.arg_name 'PATH'
|
|
@@ -36,6 +40,10 @@ class App
|
|
|
36
40
|
c.arg_name 'DEPTH'
|
|
37
41
|
c.flag %i[d depth], must_match: /^[1-9]$/, type: :integer, default_value: 1
|
|
38
42
|
|
|
43
|
+
c.desc 'Filter results using search terms'
|
|
44
|
+
c.arg_name 'QUERY'
|
|
45
|
+
c.flag %i[search find grep], multiple: true
|
|
46
|
+
|
|
39
47
|
c.desc 'Match actions containing tag. Allows value comparisons'
|
|
40
48
|
c.arg_name 'TAG'
|
|
41
49
|
c.flag %i[tagged], multiple: true
|
|
@@ -50,9 +58,12 @@ class App
|
|
|
50
58
|
c.switch %i[x exact], negatable: false
|
|
51
59
|
|
|
52
60
|
c.action do |global, options, args|
|
|
61
|
+
args.concat(options[:search])
|
|
62
|
+
|
|
53
63
|
options[:finish] = true
|
|
54
64
|
options[:f] = true
|
|
55
|
-
options[:
|
|
65
|
+
options[:to] = 'Archive' if options[:archive] && !options[:to]
|
|
66
|
+
options[:move] = 'Archive' if options[:archive] && !options[:move]
|
|
56
67
|
|
|
57
68
|
cmd = commands[:update]
|
|
58
69
|
action = cmd.send(:get_action, nil)
|
data/bin/commands/update.rb
CHANGED
|
@@ -33,7 +33,11 @@ class App
|
|
|
33
33
|
|
|
34
34
|
c.desc 'Move action to specific project'
|
|
35
35
|
c.arg_name 'PROJECT'
|
|
36
|
-
c.flag %i[to
|
|
36
|
+
c.flag %i[to move]
|
|
37
|
+
|
|
38
|
+
c.desc 'Affect actions from a specific project'
|
|
39
|
+
c.arg_name 'PROJECT[/SUBPROJECT]'
|
|
40
|
+
c.flag %i[proj project]
|
|
37
41
|
|
|
38
42
|
c.desc 'Use a known todo file, partial matches allowed'
|
|
39
43
|
c.arg_name 'TODO_FILE'
|
|
@@ -51,6 +55,10 @@ class App
|
|
|
51
55
|
c.arg_name 'TAG'
|
|
52
56
|
c.flag %i[r remove], multiple: true
|
|
53
57
|
|
|
58
|
+
c.desc 'Use with --find to find and replace with new text. Enables --exact when used'
|
|
59
|
+
c.arg_name 'TEXT'
|
|
60
|
+
c.flag %i[replace]
|
|
61
|
+
|
|
54
62
|
c.desc 'Add a @done tag to action'
|
|
55
63
|
c.switch %i[f finish], negatable: false
|
|
56
64
|
|
|
@@ -75,6 +83,10 @@ class App
|
|
|
75
83
|
c.arg_name 'DEPTH'
|
|
76
84
|
c.flag %i[d depth], must_match: /^[1-9]$/, type: :integer, default_value: 1
|
|
77
85
|
|
|
86
|
+
c.desc 'Filter results using search terms'
|
|
87
|
+
c.arg_name 'QUERY'
|
|
88
|
+
c.flag %i[search find grep], multiple: true
|
|
89
|
+
|
|
78
90
|
c.desc 'Match actions containing tag. Allows value comparisons'
|
|
79
91
|
c.arg_name 'TAG'
|
|
80
92
|
c.flag %i[tagged], multiple: true
|
|
@@ -90,6 +102,9 @@ class App
|
|
|
90
102
|
|
|
91
103
|
c.action do |global_options, options, args|
|
|
92
104
|
reader = TTY::Reader.new
|
|
105
|
+
|
|
106
|
+
args.concat(options[:search])
|
|
107
|
+
|
|
93
108
|
append = options[:at] ? options[:at] =~ /^[ae]/i : global_options[:add_at] =~ /^[ae]/i
|
|
94
109
|
|
|
95
110
|
if options[:restore] || (!options[:remove].nil? && options[:remove].include?('done'))
|
|
@@ -97,10 +112,12 @@ class App
|
|
|
97
112
|
options[:tagged] << '+done'
|
|
98
113
|
elsif !options[:remove].nil? && !options[:remove].empty?
|
|
99
114
|
options[:tagged].concat(options[:remove])
|
|
100
|
-
elsif options[:finish]
|
|
115
|
+
elsif options[:finish] && !options[:done]
|
|
101
116
|
options[:tagged] << '-done'
|
|
102
117
|
end
|
|
103
118
|
|
|
119
|
+
options[:exact] = true unless options[:replace].nil?
|
|
120
|
+
|
|
104
121
|
action = if args.count.positive?
|
|
105
122
|
args.join(' ').strip
|
|
106
123
|
else
|
|
@@ -168,8 +185,8 @@ class App
|
|
|
168
185
|
note = stdin_note.empty? ? [] : stdin_note
|
|
169
186
|
note.concat(line_note) unless line_note.nil? || line_note.empty?
|
|
170
187
|
|
|
171
|
-
target_proj = if options[:
|
|
172
|
-
options[:
|
|
188
|
+
target_proj = if options[:move]
|
|
189
|
+
options[:move]
|
|
173
190
|
elsif NA.cwd_is == :project
|
|
174
191
|
NA.cwd
|
|
175
192
|
end
|
|
@@ -204,7 +221,7 @@ class App
|
|
|
204
221
|
files = NA.find_files_matching({
|
|
205
222
|
depth: options[:depth],
|
|
206
223
|
done: options[:done],
|
|
207
|
-
project:
|
|
224
|
+
project: options[:project],
|
|
208
225
|
regex: options[:regex],
|
|
209
226
|
require_na: false,
|
|
210
227
|
search: tokens,
|
|
@@ -219,7 +236,7 @@ class App
|
|
|
219
236
|
|
|
220
237
|
if options[:archive]
|
|
221
238
|
options[:finish] = true
|
|
222
|
-
options[:
|
|
239
|
+
options[:move] = 'Archive'
|
|
223
240
|
end
|
|
224
241
|
|
|
225
242
|
NA.notify("#{NA.theme[:error]}No search terms provided", exit_code: 1) if tokens.nil? && options[:tagged].empty?
|
|
@@ -233,11 +250,13 @@ class App
|
|
|
233
250
|
done: options[:done],
|
|
234
251
|
edit: options[:edit],
|
|
235
252
|
finish: options[:finish],
|
|
253
|
+
move: target_proj,
|
|
236
254
|
note: note,
|
|
237
255
|
overwrite: options[:overwrite],
|
|
238
256
|
priority: priority,
|
|
239
|
-
project:
|
|
257
|
+
project: options[:project],
|
|
240
258
|
remove_tag: remove_tags,
|
|
259
|
+
replace: options[:replace],
|
|
241
260
|
tagged: tags)
|
|
242
261
|
end
|
|
243
262
|
end
|
data/lib/na/action.rb
CHANGED
|
@@ -59,6 +59,7 @@ module NA
|
|
|
59
59
|
@project: #{@project}
|
|
60
60
|
@parent: #{@parent.join('>')}
|
|
61
61
|
@action: #{@action}
|
|
62
|
+
@tags: #{@tags}
|
|
62
63
|
@note: #{@note}
|
|
63
64
|
EOINSPECT
|
|
64
65
|
end
|
|
@@ -94,14 +95,8 @@ module NA
|
|
|
94
95
|
file_tpl = "#{template[:file]}#{file} {x}"
|
|
95
96
|
filename = NA::Color.template(file_tpl)
|
|
96
97
|
|
|
97
|
-
# Add notes if needed
|
|
98
|
-
note = if notes && @note.count.positive?
|
|
99
|
-
NA::Color.template("\n#{@note.map { |l| " #{template[:note]}• #{l}{x}" }.join("\n")}")
|
|
100
|
-
else
|
|
101
|
-
''
|
|
102
|
-
end
|
|
103
|
-
|
|
104
98
|
# colorize the action and highlight tags
|
|
99
|
+
@action.gsub!(/\{(.*?)\}/, '\\{\1\\}')
|
|
105
100
|
action = NA::Color.template("#{template[:action]}#{@action.sub(/ @#{NA.na_tag}\b/, '')}{x}")
|
|
106
101
|
action = action.highlight_tags(color: template[:tags],
|
|
107
102
|
parens: template[:value_parens],
|
|
@@ -110,9 +105,27 @@ module NA
|
|
|
110
105
|
|
|
111
106
|
if detect_width
|
|
112
107
|
width = TTY::Screen.columns
|
|
113
|
-
prefix = NA::Color.uncolor(pretty(template: { templates: { output: template[:templates][:output].sub(/%action/, '') } }, detect_width: false))
|
|
108
|
+
prefix = NA::Color.uncolor(pretty(template: { templates: { output: template[:templates][:output].sub(/%action/, '').sub(/%note/, '') } }, detect_width: false))
|
|
114
109
|
indent = prefix.length
|
|
110
|
+
|
|
111
|
+
# Add notes if needed
|
|
112
|
+
note = if notes && @note.count.positive?
|
|
113
|
+
NA::Color.template(@note.wrap(width, indent, template[:note]))
|
|
114
|
+
elsif !notes && @note.count.positive?
|
|
115
|
+
action += "#{template[:note]}*"
|
|
116
|
+
else
|
|
117
|
+
''
|
|
118
|
+
end
|
|
119
|
+
|
|
115
120
|
action = action.wrap(width, indent)
|
|
121
|
+
else
|
|
122
|
+
note = if notes && @note.count.positive?
|
|
123
|
+
NA::Color.template("\n#{@note.map { |l| " #{template[:note]}• #{l.wrap(width, indent)}{x}" }.join("\n")}")
|
|
124
|
+
elsif !notes && @note.count.positive?
|
|
125
|
+
action += "#{template[:note]}*"
|
|
126
|
+
else
|
|
127
|
+
''
|
|
128
|
+
end
|
|
116
129
|
end
|
|
117
130
|
|
|
118
131
|
# Replace variables in template string and output colorized
|
|
@@ -184,7 +197,6 @@ module NA
|
|
|
184
197
|
return false if keys.empty?
|
|
185
198
|
|
|
186
199
|
key = keys[0]
|
|
187
|
-
|
|
188
200
|
return true if tag[:comp].nil?
|
|
189
201
|
|
|
190
202
|
tag_val = @tags[key]
|
data/lib/na/actions.rb
CHANGED
|
@@ -79,7 +79,7 @@ module NA
|
|
|
79
79
|
|
|
80
80
|
files.map { |f| NA.notify(f, debug: true) } if files
|
|
81
81
|
|
|
82
|
-
output = map { |action| action.pretty(template: { output: template }, regexes: regexes, notes: notes) }
|
|
82
|
+
output = map { |action| action.pretty(template: { templates: { output: template } }, regexes: regexes, notes: notes) }
|
|
83
83
|
NA::Pager.page(output.join("\n"))
|
|
84
84
|
end
|
|
85
85
|
end
|
data/lib/na/array.rb
CHANGED
|
@@ -10,4 +10,11 @@ class ::Array
|
|
|
10
10
|
def remove_bad
|
|
11
11
|
compact.map { |x| x.is_a?(String) ? x.strip : x }.select(&:good?)
|
|
12
12
|
end
|
|
13
|
+
|
|
14
|
+
def wrap(width, indent, color)
|
|
15
|
+
map! do |l|
|
|
16
|
+
"#{color}#{' ' * indent }• #{l.wrap(width, indent)}{x}"
|
|
17
|
+
end
|
|
18
|
+
"\n#{join("\n")}"
|
|
19
|
+
end
|
|
13
20
|
end
|
data/lib/na/next_action.rb
CHANGED
|
@@ -139,10 +139,11 @@ module NA
|
|
|
139
139
|
todo.projects
|
|
140
140
|
end
|
|
141
141
|
|
|
142
|
-
def find_actions(target, search, tagged = nil, all: false, done: false)
|
|
142
|
+
def find_actions(target, search, tagged = nil, all: false, done: false, project: nil)
|
|
143
143
|
todo = NA::Todo.new({ search: search,
|
|
144
144
|
require_na: false,
|
|
145
145
|
file_path: target,
|
|
146
|
+
project: project,
|
|
146
147
|
tag: tagged,
|
|
147
148
|
done: done })
|
|
148
149
|
|
|
@@ -241,20 +242,23 @@ module NA
|
|
|
241
242
|
overwrite: false,
|
|
242
243
|
priority: 0,
|
|
243
244
|
project: nil,
|
|
245
|
+
move: nil,
|
|
244
246
|
remove_tag: [],
|
|
247
|
+
replace: nil,
|
|
245
248
|
tagged: nil)
|
|
246
249
|
|
|
247
250
|
projects = find_projects(target)
|
|
248
251
|
|
|
249
252
|
target_proj = nil
|
|
250
253
|
|
|
251
|
-
if
|
|
252
|
-
|
|
253
|
-
target_proj = projects.select { |pr| pr.project =~ /#{
|
|
254
|
+
if move
|
|
255
|
+
move = move.sub(/:$/, '')
|
|
256
|
+
target_proj = projects.select { |pr| pr.project =~ /#{move.gsub(/:/, '.*?:.*?')}/i }.first
|
|
254
257
|
if target_proj.nil?
|
|
255
|
-
res = NA.yn(NA::Color.template("#{NA.theme[:warning]}Project #{NA.theme[:file]}#{
|
|
258
|
+
res = NA.yn(NA::Color.template("#{NA.theme[:warning]}Project #{NA.theme[:file]}#{move}#{NA.theme[:warning]} doesn't exist, add it"), default: true)
|
|
256
259
|
if res
|
|
257
|
-
target_proj = insert_project(target,
|
|
260
|
+
target_proj = insert_project(target, move, projects)
|
|
261
|
+
projects << target_proj
|
|
258
262
|
else
|
|
259
263
|
NA.notify("#{NA.theme[:error]}Cancelled", exit_code: 1)
|
|
260
264
|
end
|
|
@@ -308,7 +312,7 @@ module NA
|
|
|
308
312
|
|
|
309
313
|
notify(add.pretty)
|
|
310
314
|
else
|
|
311
|
-
_, actions = find_actions(target, search, tagged, done: done, all: all)
|
|
315
|
+
_, actions = find_actions(target, search, tagged, done: done, all: all, project: project)
|
|
312
316
|
|
|
313
317
|
return if actions.nil?
|
|
314
318
|
|
|
@@ -325,6 +329,9 @@ module NA
|
|
|
325
329
|
action.note = new_note
|
|
326
330
|
end
|
|
327
331
|
|
|
332
|
+
# If replace is defined, use search to search and replace text in action
|
|
333
|
+
action.action.sub!(Regexp.new(Regexp.escape(search), Regexp::IGNORECASE), replace) if replace
|
|
334
|
+
|
|
328
335
|
action.process(priority: priority, finish: finish, add_tag: add_tag, remove_tag: remove_tag)
|
|
329
336
|
|
|
330
337
|
target_proj = if target_proj
|
|
@@ -489,23 +496,22 @@ module NA
|
|
|
489
496
|
tag: nil
|
|
490
497
|
}
|
|
491
498
|
opts = defaults.merge(options)
|
|
492
|
-
|
|
493
499
|
files = find_files(depth: options[:depth])
|
|
494
|
-
|
|
495
500
|
files.delete_if do |file|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
todo.
|
|
501
|
+
cmd_options = {
|
|
502
|
+
depth: options[:depth],
|
|
503
|
+
done: options[:done],
|
|
504
|
+
file_path: file,
|
|
505
|
+
negate: options[:negate],
|
|
506
|
+
project: options[:project],
|
|
507
|
+
query: options[:query],
|
|
508
|
+
regex: options[:regex],
|
|
509
|
+
require_na: options[:require_na],
|
|
510
|
+
search: options[:search],
|
|
511
|
+
tag: options[:tag]
|
|
512
|
+
}
|
|
513
|
+
todo = NA::Todo.new(cmd_options)
|
|
514
|
+
todo.actions.empty?
|
|
509
515
|
end
|
|
510
516
|
|
|
511
517
|
files
|
data/lib/na/todo.rb
CHANGED
|
@@ -61,7 +61,7 @@ module NA
|
|
|
61
61
|
required_tag.push(t) if t[:required] && t[:negate]
|
|
62
62
|
negated_tag.push(t) unless t[:negate]
|
|
63
63
|
else
|
|
64
|
-
optional_tag.push(t) unless t[:negate]
|
|
64
|
+
optional_tag.push(t) unless t[:negate] || t[:required]
|
|
65
65
|
required_tag.push(t) if t[:required] && !t[:negate]
|
|
66
66
|
negated_tag.push(t) if t[:negate]
|
|
67
67
|
end
|
|
@@ -133,11 +133,9 @@ module NA
|
|
|
133
133
|
next if settings[:require_na] && !line.na?
|
|
134
134
|
|
|
135
135
|
has_search = !optional.empty? || !required.empty? || !negated.empty?
|
|
136
|
-
|
|
137
136
|
next if has_search && !new_action.search_match?(any: optional,
|
|
138
137
|
all: required,
|
|
139
138
|
none: negated)
|
|
140
|
-
|
|
141
139
|
if settings[:project]
|
|
142
140
|
rx = settings[:project].split(%r{[/:]}).join('.*?/')
|
|
143
141
|
next unless parent.join('/') =~ Regexp.new("#{rx}.*?", Regexp::IGNORECASE)
|
data/lib/na/version.rb
CHANGED
data/src/_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 <!--VER-->1.2.
|
|
12
|
+
The current version of `na` is <!--VER-->1.2.46<!--END VER-->.
|
|
13
13
|
|
|
14
14
|
`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.
|
|
15
15
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: na
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.47
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brett Terpstra
|
|
@@ -246,7 +246,6 @@ files:
|
|
|
246
246
|
- na.rdoc
|
|
247
247
|
- scripts/fixreadme.rb
|
|
248
248
|
- src/_README.md
|
|
249
|
-
- test2.txt
|
|
250
249
|
homepage: https://brettterpstra.com/projects/na/
|
|
251
250
|
licenses:
|
|
252
251
|
- MIT
|