na 1.2.13 → 1.2.15
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/CHANGELOG.md +22 -0
- data/Gemfile.lock +1 -1
- data/README.md +11 -2
- data/bin/na +112 -4
- data/lib/na/next_action.rb +27 -25
- data/lib/na/string.rb +29 -0
- data/lib/na/version.rb +1 -1
- data/src/README.md +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4d2ce71562668eb958d8056e6f226329839fe872575eb0f6dba5220aedbc09a5
|
|
4
|
+
data.tar.gz: c1461870c50b6665a0269c7be2e05130cf8c94ab1fd8a929b4566c391b81a8e4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f5fe87068b1ad84b747f35e255ddd64687c90733b9526e41c258e13557ccc9396b8025ef42acf3fd90a7facb6049a4907f099c36f8ef4977ac479aab5d451a07
|
|
7
|
+
data.tar.gz: 702e69f47f8baf069fe398ac3daac5615c56095377df31b91e93edb6a94dae8682ab4fb2574c8f57b419a6ddf2fc61938def7c598990c60aeb722ccb7af9f97b
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
### 1.2.15
|
|
2
|
+
|
|
3
|
+
2022-11-28 10:58
|
|
4
|
+
|
|
5
|
+
#### FIXED
|
|
6
|
+
|
|
7
|
+
- `na update` error when not moving project
|
|
8
|
+
|
|
9
|
+
### 1.2.14
|
|
10
|
+
|
|
11
|
+
2022-11-12 10:57
|
|
12
|
+
|
|
13
|
+
#### NEW
|
|
14
|
+
|
|
15
|
+
- `na find --tagged` allows narrowing search results with tag queries
|
|
16
|
+
- `na tagged --search` allows narrowing tag results with text search
|
|
17
|
+
- `na next` accepts --tagged and --search (as well as --exact and --regex) for filtering actions
|
|
18
|
+
|
|
19
|
+
#### FIXED
|
|
20
|
+
|
|
21
|
+
- Error when a todo file contained a task without a project
|
|
22
|
+
|
|
1
23
|
### 1.2.13
|
|
2
24
|
|
|
3
25
|
2022-11-01 12:43
|
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.15
|
|
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.15
|
|
81
81
|
|
|
82
82
|
GLOBAL OPTIONS
|
|
83
83
|
-a, --[no-]add - Add a next action (deprecated, for backwards compatibility)
|
|
@@ -214,6 +214,7 @@ COMMAND OPTIONS
|
|
|
214
214
|
-o, --or - Combine search tokens with OR, displaying actions matching ANY of the terms
|
|
215
215
|
--proj, --project=PROJECT[/SUBPROJECT] - Show actions from a specific project (default: none)
|
|
216
216
|
--save=TITLE - Save this search for future use (default: none)
|
|
217
|
+
--tagged=TAG - Match actions containing tag. Allows value comparisons (may be used more than once, default: none)
|
|
217
218
|
-v, --invert - Show actions not matching search pattern
|
|
218
219
|
-x, --exact - Match pattern exactly
|
|
219
220
|
|
|
@@ -269,10 +270,14 @@ DESCRIPTION
|
|
|
269
270
|
COMMAND OPTIONS
|
|
270
271
|
-d, --depth=DEPTH - Recurse to depth (default: none)
|
|
271
272
|
--[no-]done - Include @done actions
|
|
273
|
+
--[no-]exact - Search query is exact text match (not tokens)
|
|
272
274
|
--in, --todo=TODO_FILE - Display matches from a known todo file (may be used more than once, default: none)
|
|
273
275
|
--[no-]notes - Include notes in output
|
|
274
276
|
--proj, --project=PROJECT[/SUBPROJECT] - Show actions from a specific project (default: none)
|
|
277
|
+
--[no-]regex - Search query is regular expression
|
|
278
|
+
--search=QUERY - Filter results using search terms (may be used more than once, default: none)
|
|
275
279
|
-t, --tag=TAG - Alternate tag to search for (default: none)
|
|
280
|
+
--tagged=TAG - Match actions containing tag. Allows value comparisons (may be used more than once, default: none)
|
|
276
281
|
|
|
277
282
|
EXAMPLES
|
|
278
283
|
|
|
@@ -369,10 +374,14 @@ DESCRIPTION
|
|
|
369
374
|
COMMAND OPTIONS
|
|
370
375
|
-d, --depth=DEPTH - Recurse to depth (default: none)
|
|
371
376
|
--[no-]done - Include @done actions
|
|
377
|
+
--[no-]exact - Search query is exact text match (not tokens)
|
|
372
378
|
--in, --todo=TODO_FILE - Display matches from a known todo file (may be used more than once, default: none)
|
|
373
379
|
--[no-]notes - Include notes in output
|
|
374
380
|
--proj, --project=PROJECT[/SUBPROJECT] - Show actions from a specific project (default: none)
|
|
381
|
+
--[no-]regex - Search query is regular expression
|
|
382
|
+
--search=QUERY - Filter results using search terms (may be used more than once, default: none)
|
|
375
383
|
-t, --tag=TAG - Alternate tag to search for (default: none)
|
|
384
|
+
--tagged=TAG - Match actions containing tag. Allows value comparisons (may be used more than once, default: none)
|
|
376
385
|
|
|
377
386
|
EXAMPLES
|
|
378
387
|
|
data/bin/na
CHANGED
|
@@ -95,6 +95,20 @@ class App
|
|
|
95
95
|
c.arg_name 'PROJECT[/SUBPROJECT]'
|
|
96
96
|
c.flag %i[proj project]
|
|
97
97
|
|
|
98
|
+
c.desc 'Match actions containing tag. Allows value comparisons'
|
|
99
|
+
c.arg_name 'TAG'
|
|
100
|
+
c.flag %i[tagged], multiple: true
|
|
101
|
+
|
|
102
|
+
c.desc 'Filter results using search terms'
|
|
103
|
+
c.arg_name 'QUERY'
|
|
104
|
+
c.flag %i[search], multiple: true
|
|
105
|
+
|
|
106
|
+
c.desc 'Search query is regular expression'
|
|
107
|
+
c.switch %i[regex]
|
|
108
|
+
|
|
109
|
+
c.desc 'Search query is exact text match (not tokens)'
|
|
110
|
+
c.switch %i[exact]
|
|
111
|
+
|
|
98
112
|
c.desc 'Include notes in output'
|
|
99
113
|
c.switch %i[notes], negatable: true, default_value: false
|
|
100
114
|
|
|
@@ -117,6 +131,20 @@ class App
|
|
|
117
131
|
options[:depth].nil? ? global_options[:depth].to_i : options[:depth].to_i
|
|
118
132
|
end
|
|
119
133
|
|
|
134
|
+
all_req = options[:tagged].join(' ') !~ /[+!\-]/ && !options[:or]
|
|
135
|
+
tags = []
|
|
136
|
+
options[:tagged].join(',').split(/ *, */).each do |arg|
|
|
137
|
+
m = arg.match(/^(?<req>[+\-!])?(?<tag>[^ =<>$\^]+?)(?:(?<op>[=<>]{1,2}|[*$\^]=)(?<val>.*?))?$/)
|
|
138
|
+
|
|
139
|
+
tags.push({
|
|
140
|
+
tag: m['tag'].wildcard_to_rx,
|
|
141
|
+
comp: m['op'],
|
|
142
|
+
value: m['val'],
|
|
143
|
+
required: all_req || (!m['req'].nil? && m['req'] == '+'),
|
|
144
|
+
negate: !m['req'].nil? && m['req'] =~ /[!\-]/
|
|
145
|
+
})
|
|
146
|
+
end
|
|
147
|
+
|
|
120
148
|
args.concat(options[:in])
|
|
121
149
|
if args.count.positive?
|
|
122
150
|
all_req = args.join(' ') !~ /[+!\-]/
|
|
@@ -134,14 +162,37 @@ class App
|
|
|
134
162
|
end
|
|
135
163
|
end
|
|
136
164
|
|
|
165
|
+
search = nil
|
|
166
|
+
if options[:search]
|
|
167
|
+
if options[:exact]
|
|
168
|
+
search = options[:search].join(' ')
|
|
169
|
+
elsif options[:regex]
|
|
170
|
+
search = Regexp.new(options[:search].join(' '), Regexp::IGNORECASE)
|
|
171
|
+
else
|
|
172
|
+
search = []
|
|
173
|
+
all_req = options[:search].join(' ') !~ /[+!\-]/ && !options[:or]
|
|
174
|
+
|
|
175
|
+
options[:search].join(' ').split(/ /).each do |arg|
|
|
176
|
+
m = arg.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
|
|
177
|
+
search.push({
|
|
178
|
+
token: m['tok'],
|
|
179
|
+
required: all_req || (!m['req'].nil? && m['req'] == '+'),
|
|
180
|
+
negate: !m['req'].nil? && m['req'] =~ /[!\-]/
|
|
181
|
+
})
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
137
186
|
NA.na_tag = options[:tag] unless options[:tag].nil?
|
|
138
187
|
require_na = true
|
|
139
188
|
|
|
140
|
-
tag = [{ tag:
|
|
189
|
+
tag = [{ tag: NA.na_tag, value: nil }, { tag: 'done', value: nil, negate: true }]
|
|
190
|
+
tag.concat(tags)
|
|
141
191
|
files, actions, = NA.parse_actions(depth: depth,
|
|
142
192
|
done: options[:done],
|
|
143
193
|
query: tokens,
|
|
144
194
|
tag: tag,
|
|
195
|
+
search: search,
|
|
145
196
|
project: options[:project],
|
|
146
197
|
require_na: require_na)
|
|
147
198
|
|
|
@@ -587,6 +638,10 @@ class App
|
|
|
587
638
|
c.arg_name 'PROJECT[/SUBPROJECT]'
|
|
588
639
|
c.flag %i[proj project]
|
|
589
640
|
|
|
641
|
+
c.desc 'Match actions containing tag. Allows value comparisons'
|
|
642
|
+
c.arg_name 'TAG'
|
|
643
|
+
c.flag %i[tagged], multiple: true
|
|
644
|
+
|
|
590
645
|
c.desc 'Include @done actions'
|
|
591
646
|
c.switch %i[done]
|
|
592
647
|
|
|
@@ -600,7 +655,7 @@ class App
|
|
|
600
655
|
c.action do |global_options, options, args|
|
|
601
656
|
if options[:save]
|
|
602
657
|
title = options[:save].gsub(/[^a-z0-9]/, '_').gsub(/_+/, '_')
|
|
603
|
-
NA.save_search(title, "#{NA.command_line.join(' ').sub(/ --save[= ]*\S+/, '')}")
|
|
658
|
+
NA.save_search(title, "#{NA.command_line.join(' ').sub(/ --save[= ]*\S+/, '').split(' ').map { |t| %("#{t}") }.join(' ')}")
|
|
604
659
|
end
|
|
605
660
|
|
|
606
661
|
depth = if global_options[:recurse] && options[:depth].nil? && global_options[:depth] == 1
|
|
@@ -608,6 +663,21 @@ class App
|
|
|
608
663
|
else
|
|
609
664
|
options[:depth].nil? ? global_options[:depth].to_i : options[:depth].to_i
|
|
610
665
|
end
|
|
666
|
+
|
|
667
|
+
all_req = options[:tagged].join(' ') !~ /[+!\-]/ && !options[:or]
|
|
668
|
+
tags = []
|
|
669
|
+
options[:tagged].join(',').split(/ *, */).each do |arg|
|
|
670
|
+
m = arg.match(/^(?<req>[+\-!])?(?<tag>[^ =<>$\^]+?)(?:(?<op>[=<>]{1,2}|[*$\^]=)(?<val>.*?))?$/)
|
|
671
|
+
|
|
672
|
+
tags.push({
|
|
673
|
+
tag: m['tag'].wildcard_to_rx,
|
|
674
|
+
comp: m['op'],
|
|
675
|
+
value: m['val'],
|
|
676
|
+
required: all_req || (!m['req'].nil? && m['req'] == '+'),
|
|
677
|
+
negate: !m['req'].nil? && m['req'] =~ /[!\-]/
|
|
678
|
+
})
|
|
679
|
+
end
|
|
680
|
+
|
|
611
681
|
tokens = nil
|
|
612
682
|
if options[:exact]
|
|
613
683
|
tokens = args.join(' ')
|
|
@@ -644,6 +714,7 @@ class App
|
|
|
644
714
|
done: options[:done],
|
|
645
715
|
query: todo,
|
|
646
716
|
search: tokens,
|
|
717
|
+
tag: tags,
|
|
647
718
|
negate: options[:invert],
|
|
648
719
|
regex: options[:regex],
|
|
649
720
|
project: options[:project],
|
|
@@ -692,6 +763,16 @@ class App
|
|
|
692
763
|
c.arg_name 'PROJECT[/SUBPROJECT]'
|
|
693
764
|
c.flag %i[proj project]
|
|
694
765
|
|
|
766
|
+
c.desc 'Filter results using search terms'
|
|
767
|
+
c.arg_name 'QUERY'
|
|
768
|
+
c.flag %i[search], multiple: true
|
|
769
|
+
|
|
770
|
+
c.desc 'Search query is regular expression'
|
|
771
|
+
c.switch %i[regex]
|
|
772
|
+
|
|
773
|
+
c.desc 'Search query is exact text match (not tokens)'
|
|
774
|
+
c.switch %i[exact]
|
|
775
|
+
|
|
695
776
|
c.desc 'Include @done actions'
|
|
696
777
|
c.switch %i[done]
|
|
697
778
|
|
|
@@ -705,7 +786,7 @@ class App
|
|
|
705
786
|
c.action do |global_options, options, args|
|
|
706
787
|
if options[:save]
|
|
707
788
|
title = options[:save].gsub(/[^a-z0-9]/, '_').gsub(/_+/, '_')
|
|
708
|
-
NA.save_search(title, "#{NA.command_line.join(' ').sub(/ --save[= ]*\S+/, '')}")
|
|
789
|
+
NA.save_search(title, "#{NA.command_line.join(' ').sub(/ --save[= ]*\S+/, '').split(' ').map { |t| %("#{t}") }.join(' ')}")
|
|
709
790
|
end
|
|
710
791
|
|
|
711
792
|
depth = if global_options[:recurse] && options[:depth].nil? && global_options[:depth] == 1
|
|
@@ -733,6 +814,27 @@ class App
|
|
|
733
814
|
tags.each { |tag| search_for_done = true if tag[:tag] =~ /done/ }
|
|
734
815
|
tags.push({ tag: 'done', value: nil, negate: true}) unless search_for_done
|
|
735
816
|
|
|
817
|
+
tokens = nil
|
|
818
|
+
if options[:search]
|
|
819
|
+
if options[:exact]
|
|
820
|
+
tokens = options[:search].join(' ')
|
|
821
|
+
elsif options[:regex]
|
|
822
|
+
tokens = Regexp.new(options[:search].join(' '), Regexp::IGNORECASE)
|
|
823
|
+
else
|
|
824
|
+
tokens = []
|
|
825
|
+
all_req = options[:search].join(' ') !~ /[+!\-]/ && !options[:or]
|
|
826
|
+
|
|
827
|
+
options[:search].join(' ').split(/ /).each do |arg|
|
|
828
|
+
m = arg.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
|
|
829
|
+
tokens.push({
|
|
830
|
+
token: m['tok'],
|
|
831
|
+
required: all_req || (!m['req'].nil? && m['req'] == '+'),
|
|
832
|
+
negate: !m['req'].nil? && m['req'] =~ /[!\-]/
|
|
833
|
+
})
|
|
834
|
+
end
|
|
835
|
+
end
|
|
836
|
+
end
|
|
837
|
+
|
|
736
838
|
todo = nil
|
|
737
839
|
if options[:in]
|
|
738
840
|
todo = []
|
|
@@ -749,11 +851,17 @@ class App
|
|
|
749
851
|
files, actions, = NA.parse_actions(depth: depth,
|
|
750
852
|
done: options[:done],
|
|
751
853
|
query: todo,
|
|
854
|
+
search: tokens,
|
|
752
855
|
tag: tags,
|
|
753
856
|
negate: options[:invert],
|
|
754
857
|
project: options[:project],
|
|
755
858
|
require_na: false)
|
|
756
|
-
regexes = tags.delete_if { |token| token[:negate] }.map { |token| token[:token] }
|
|
859
|
+
# regexes = tags.delete_if { |token| token[:negate] }.map { |token| token[:token] }
|
|
860
|
+
regexes = if tokens.is_a?(Array)
|
|
861
|
+
tokens.delete_if { |token| token[:negate] }.map { |token| token[:token] }
|
|
862
|
+
else
|
|
863
|
+
[tokens]
|
|
864
|
+
end
|
|
757
865
|
NA.output_actions(actions, depth, files: files, regexes: regexes, notes: options[:notes])
|
|
758
866
|
end
|
|
759
867
|
end
|
data/lib/na/next_action.rb
CHANGED
|
@@ -330,6 +330,8 @@ module NA
|
|
|
330
330
|
contents.slice!(action.line, action.note.count + 1)
|
|
331
331
|
next if delete
|
|
332
332
|
|
|
333
|
+
target_proj = action.project if target_proj.nil?
|
|
334
|
+
|
|
333
335
|
projects = shift_index_after(projects, action.line, action.note.count + 1)
|
|
334
336
|
|
|
335
337
|
target_proj = projects.select { |proj| proj.project =~ /^#{target_proj.project}$/ }.first
|
|
@@ -512,36 +514,36 @@ module NA
|
|
|
512
514
|
last_line = 0
|
|
513
515
|
in_action = false
|
|
514
516
|
content.split("\n").each.with_index do |line, idx|
|
|
515
|
-
if line
|
|
517
|
+
if line.project?
|
|
516
518
|
in_action = false
|
|
517
|
-
proj =
|
|
519
|
+
proj = line.project
|
|
518
520
|
indent = line.indent_level
|
|
519
521
|
|
|
520
|
-
if indent.zero?
|
|
522
|
+
if indent.zero? # top level project
|
|
521
523
|
parent = [proj]
|
|
522
|
-
elsif indent <= indent_level
|
|
524
|
+
elsif indent <= indent_level # if indent level is same or less, split parent before indent level and append
|
|
523
525
|
parent.slice!(indent, parent.count - indent)
|
|
524
526
|
parent.push(proj)
|
|
525
|
-
|
|
527
|
+
else # if indent level is greater, append project to parent
|
|
526
528
|
parent.push(proj)
|
|
527
529
|
end
|
|
528
530
|
|
|
529
531
|
projects.push(NA::Project.new(parent.join(':'), indent, idx, idx))
|
|
530
532
|
|
|
531
533
|
indent_level = indent
|
|
532
|
-
elsif line.
|
|
534
|
+
elsif line.blank?
|
|
533
535
|
in_action = false
|
|
534
|
-
elsif line
|
|
536
|
+
elsif line.action?
|
|
535
537
|
in_action = false
|
|
536
538
|
|
|
537
|
-
action = line.
|
|
539
|
+
action = line.action
|
|
538
540
|
new_action = NA::Action.new(file, File.basename(file, ".#{NA.extension}"), parent.dup, action, idx)
|
|
539
541
|
|
|
540
542
|
projects[-1].last_line = idx if projects.count.positive?
|
|
541
543
|
|
|
542
|
-
next if line
|
|
544
|
+
next if line.done? && !done
|
|
543
545
|
|
|
544
|
-
next if require_na && line
|
|
546
|
+
next if require_na && !line.na?
|
|
545
547
|
|
|
546
548
|
has_search = !optional.empty? || !required.empty? || !negated.empty?
|
|
547
549
|
|
|
@@ -600,11 +602,11 @@ module NA
|
|
|
600
602
|
db_dir = File.expand_path('~/.local/share/na')
|
|
601
603
|
db_file = 'tdlist.txt'
|
|
602
604
|
file = File.join(db_dir, db_file)
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
605
|
+
return unless File.exist?(file)
|
|
606
|
+
|
|
607
|
+
dirs = file.read_file.split("\n")
|
|
608
|
+
dirs.delete_if { |f| !File.exist?(f) }
|
|
609
|
+
File.open(file, 'w') { |f| f.puts dirs.join("\n") }
|
|
608
610
|
end
|
|
609
611
|
|
|
610
612
|
def list_projects(query: [], file_path: nil, depth: 1, paths: true)
|
|
@@ -624,7 +626,7 @@ module NA
|
|
|
624
626
|
output = if paths
|
|
625
627
|
"{bg}#{parts.join('{bw}/{bg}')}{x}"
|
|
626
628
|
else
|
|
627
|
-
parts.fill(
|
|
629
|
+
parts.fill('{bw}—{bg}', 0..-2)
|
|
628
630
|
"{bg}#{parts.join(' ')}{x}"
|
|
629
631
|
end
|
|
630
632
|
|
|
@@ -633,15 +635,15 @@ module NA
|
|
|
633
635
|
end
|
|
634
636
|
|
|
635
637
|
def list_todos(query: [])
|
|
636
|
-
if query
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
638
|
+
dirs = if query
|
|
639
|
+
match_working_dir(query, distance: 2, require_last: false)
|
|
640
|
+
else
|
|
641
|
+
file = database_path
|
|
642
|
+
content = File.exist?(file) ? file.read_file.strip : ''
|
|
643
|
+
notify('{br}Database empty', exit_code: 1) if content.empty?
|
|
644
|
+
|
|
645
|
+
content.split(/\n/)
|
|
646
|
+
end
|
|
645
647
|
|
|
646
648
|
dirs.map! do |dir|
|
|
647
649
|
"{xg}#{dir.sub(/^#{ENV['HOME']}/, '~').sub(%r{/([^/]+)\.#{NA.extension}$}, '/{xbw}\1{x}')}"
|
data/lib/na/string.rb
CHANGED
|
@@ -22,6 +22,35 @@ class ::String
|
|
|
22
22
|
prefix[1].gsub(/ /, "\t").scan(/\t/).count
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
def action?
|
|
26
|
+
self =~ /^[ \t]*- /
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def blank?
|
|
30
|
+
strip =~ /^$/
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def project?
|
|
34
|
+
!action? && self =~ /:( +@\S+(\([^)]*\))?)*$/
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def project
|
|
38
|
+
m = match(/^([ \t]*)([^\-][^@()]+?): *(@\S+ *)*$/)
|
|
39
|
+
m ? m[2] : nil
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def action
|
|
43
|
+
sub(/^[ \t]*- /, '')
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def done?
|
|
47
|
+
self =~ /@done/
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def na?
|
|
51
|
+
self =~ /@#{NA.na_tag}\b/
|
|
52
|
+
end
|
|
53
|
+
|
|
25
54
|
##
|
|
26
55
|
## Colorize @tags with ANSI escapes
|
|
27
56
|
##
|
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.14<!--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,14 +1,14 @@
|
|
|
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.15
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brett Terpstra
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-11-
|
|
11
|
+
date: 2022-11-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|