na 1.1.21 → 1.1.22
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 +15 -0
- data/Gemfile.lock +1 -1
- data/README.md +8 -8
- data/bin/na +38 -22
- data/lib/na/next_action.rb +6 -6
- data/lib/na/string.rb +52 -8
- data/lib/na/version.rb +1 -1
- data/src/README.md +4 -4
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 584d55c84c26fddeb65bf537b4743b5cac4308f39d796d336d95c900fc966deb
|
4
|
+
data.tar.gz: 73ea4289a1e43ce0b67f66f803a0db07359fe3f077358328a58c172c06daa107
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89945d2a8df1c1ea11360da4258c09f9b5c8ad38f41ca5ef98a68b99c33b41fb0b718919cc680eb356903f284cef8dd4271acea94af7f8c4adca031d445a6a26
|
7
|
+
data.tar.gz: 7c3f8c30bf5a4c69270641aadfb036303c42ee8678a09c2e8b5faad7883aff0ac0139caf465f9d37b84cf170ed4ee072ad20d4872b8c760b97d0e2ca1f3b6e2e
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
### 1.1.22
|
2
|
+
|
3
|
+
2022-10-07 05:58
|
4
|
+
|
5
|
+
#### IMPROVED
|
6
|
+
|
7
|
+
- Help output and code documentation
|
8
|
+
- Allow wildcards (* and ?) when matching todo history
|
9
|
+
- Allow multiple todo queries separated by comma
|
10
|
+
|
11
|
+
#### FIXED
|
12
|
+
|
13
|
+
- Remove file extension when matching todo history
|
14
|
+
- Todo history query failed on exact match
|
15
|
+
|
1
16
|
### 1.1.21
|
2
17
|
|
3
18
|
2022-10-07 04:26
|
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.1.
|
12
|
+
The current version of `na` is 1.1.22
|
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.
|
@@ -59,7 +59,7 @@ SYNOPSIS
|
|
59
59
|
na [global options] command [command options] [arguments...]
|
60
60
|
|
61
61
|
VERSION
|
62
|
-
1.1.
|
62
|
+
1.1.22
|
63
63
|
|
64
64
|
GLOBAL OPTIONS
|
65
65
|
-a, --[no-]add - Add a next action (deprecated, for backwards compatibility)
|
@@ -171,7 +171,7 @@ DESCRIPTION
|
|
171
171
|
COMMAND OPTIONS
|
172
172
|
-d, --depth=DEPTH - Recurse to depth (default: none)
|
173
173
|
-e, --regex - Interpret search pattern as regular expression
|
174
|
-
--in=TODO_PATH - Show actions from a specific todo file in history (default: none)
|
174
|
+
--in=TODO_PATH - Show actions from a specific todo file in history. May use wildcards (* and ?) (default: none)
|
175
175
|
-o, --or - Combine search tokens with OR, displaying actions matching ANY of the terms
|
176
176
|
--proj, --project=PROJECT[/SUBPROJECT] - Show actions from a specific project (default: none)
|
177
177
|
-v, --invert - Show actions not matching search pattern
|
@@ -209,9 +209,9 @@ EXAMPLES
|
|
209
209
|
|
210
210
|
Examples:
|
211
211
|
|
212
|
-
- `na
|
213
|
-
- `na
|
214
|
-
- `na
|
212
|
+
- `na next` (list all next actions in the current directory)
|
213
|
+
- `na next -d 3` (list all next actions in the current directory and look for additional files 3 levels deep from there)
|
214
|
+
- `na next marked2` (show next actions from another directory you've previously used na on)
|
215
215
|
|
216
216
|
```
|
217
217
|
NAME
|
@@ -222,7 +222,7 @@ SYNOPSIS
|
|
222
222
|
na [global options] next [command options] [QUERY]
|
223
223
|
|
224
224
|
DESCRIPTION
|
225
|
-
Next actions are actions which contain the next action tag (default @na), do not contain @done, and are not in the Archive project.
|
225
|
+
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).
|
226
226
|
|
227
227
|
COMMAND OPTIONS
|
228
228
|
-d, --depth=DEPTH - Recurse to depth (default: 2)
|
@@ -256,7 +256,7 @@ SYNOPSIS
|
|
256
256
|
na [global options] next [command options] [QUERY]
|
257
257
|
|
258
258
|
DESCRIPTION
|
259
|
-
Next actions are actions which contain the next action tag (default @na), do not contain @done, and are not in the Archive project.
|
259
|
+
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).
|
260
260
|
|
261
261
|
COMMAND OPTIONS
|
262
262
|
-d, --depth=DEPTH - Recurse to depth (default: 2)
|
data/bin/na
CHANGED
@@ -54,8 +54,12 @@ class App
|
|
54
54
|
switch %i[debug]
|
55
55
|
|
56
56
|
desc 'Show next actions'
|
57
|
-
long_desc
|
58
|
-
do not contain @done, and are not in the Archive project.
|
57
|
+
long_desc 'Next actions are actions which contain the next action tag (default @na),
|
58
|
+
do not contain @done, and are not in the Archive project.
|
59
|
+
|
60
|
+
Arguments will target a todo file from history, whether it\'s in the current
|
61
|
+
directory or not. Todo file queries can include path components separated by /
|
62
|
+
or :, and may use wildcards (`*` to match any text, `?` to match a single character). Multiple queries allowed (separate arguments or separated by comma).'
|
59
63
|
arg_name 'QUERY', optional: true
|
60
64
|
command %i[next show] do |c|
|
61
65
|
c.example 'na next', desc: 'display the next actions from any todo files in the current directory'
|
@@ -93,11 +97,13 @@ class App
|
|
93
97
|
if args.count.positive?
|
94
98
|
tokens = []
|
95
99
|
args.each do |arg|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
100
|
+
arg.split(/ *, */).each do |a|
|
101
|
+
m = a.match(/^(?<req>\+)?(?<tok>.*?)$/)
|
102
|
+
tokens.push({
|
103
|
+
token: m['tok'],
|
104
|
+
required: !m['req'].nil?
|
105
|
+
})
|
106
|
+
end
|
101
107
|
end
|
102
108
|
end
|
103
109
|
|
@@ -251,7 +257,7 @@ class App
|
|
251
257
|
c.arg_name 'DEPTH'
|
252
258
|
c.flag %i[d depth], type: :integer, must_match: /^\d+$/
|
253
259
|
|
254
|
-
c.desc 'Show actions from a specific todo file in history'
|
260
|
+
c.desc 'Show actions from a specific todo file in history. May use wildcards (* and ?)'
|
255
261
|
c.arg_name 'TODO_PATH'
|
256
262
|
c.flag %i[in]
|
257
263
|
|
@@ -292,10 +298,14 @@ class App
|
|
292
298
|
|
293
299
|
todo = nil
|
294
300
|
if options[:in]
|
295
|
-
todo = [
|
296
|
-
|
297
|
-
|
298
|
-
|
301
|
+
todo = []
|
302
|
+
options[:in].split(/ *, */).each do |a|
|
303
|
+
m = a.match(/^(?<req>\+)?(?<tok>.*?)$/)
|
304
|
+
todo.push({
|
305
|
+
token: m['tok'],
|
306
|
+
required: !m['req'].nil?
|
307
|
+
})
|
308
|
+
end
|
299
309
|
end
|
300
310
|
|
301
311
|
files, actions = NA.parse_actions(depth: depth,
|
@@ -335,7 +345,7 @@ class App
|
|
335
345
|
c.default_value 1
|
336
346
|
c.flag %i[d depth], type: :integer, must_match: /^\d+$/
|
337
347
|
|
338
|
-
c.desc 'Show actions from a specific todo file in history'
|
348
|
+
c.desc 'Show actions from a specific todo file in history. May use wildcards (* and ?)'
|
339
349
|
c.arg_name 'TODO_PATH'
|
340
350
|
c.flag %i[in]
|
341
351
|
|
@@ -373,10 +383,14 @@ class App
|
|
373
383
|
|
374
384
|
todo = nil
|
375
385
|
if options[:in]
|
376
|
-
todo = [
|
377
|
-
|
378
|
-
|
379
|
-
|
386
|
+
todo = []
|
387
|
+
options[:in].split(/ *, */).each do |a|
|
388
|
+
m = a.match(/^(?<req>\+)?(?<tok>.*?)$/)
|
389
|
+
todo.push({
|
390
|
+
token: m['tok'],
|
391
|
+
required: !m['req'].nil?
|
392
|
+
})
|
393
|
+
end
|
380
394
|
end
|
381
395
|
|
382
396
|
files, actions = NA.parse_actions(depth: depth,
|
@@ -469,11 +483,13 @@ class App
|
|
469
483
|
if args.count.positive?
|
470
484
|
tokens = []
|
471
485
|
args.each do |arg|
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
486
|
+
arg.split(/ *, */).each do |a|
|
487
|
+
m = a.match(/^(?<req>\+)?(?<tok>.*?)$/)
|
488
|
+
tokens.push({
|
489
|
+
token: m['tok'],
|
490
|
+
required: !m['req'].nil?
|
491
|
+
})
|
492
|
+
end
|
477
493
|
end
|
478
494
|
end
|
479
495
|
|
data/lib/na/next_action.rb
CHANGED
@@ -379,18 +379,18 @@ module NA
|
|
379
379
|
## between characters
|
380
380
|
##
|
381
381
|
def match_working_dir(search, distance: 1)
|
382
|
-
search = search.map { |t| t[:token] }.join('/')
|
383
|
-
optional = [search]
|
384
|
-
required = [search]
|
385
|
-
|
386
382
|
file = database_path
|
387
383
|
notify('{r}No na database found', exit_code: 1) unless File.exist?(file)
|
388
384
|
|
389
385
|
dirs = IO.read(file).split("\n")
|
390
386
|
|
391
|
-
|
387
|
+
optional = search.map { |t| t[:token] }
|
388
|
+
required = search.filter { |s| s[:required] }.map { |t| t[:token] }
|
389
|
+
|
390
|
+
NA.notify("{bw}Optional directory regex: {x}#{optional.map(&:dir_to_rx)}", debug: true)
|
391
|
+
NA.notify("{bw}Required directory regex: {x}#{required.map(&:dir_to_rx)}", debug: true)
|
392
392
|
|
393
|
-
dirs.delete_if { |d| !d.dir_matches(any: optional, all: required) }
|
393
|
+
dirs.delete_if { |d| !d.sub(/\.#{NA.extension}$/, '').dir_matches(any: optional, all: required) }
|
394
394
|
dirs.sort.uniq
|
395
395
|
end
|
396
396
|
|
data/lib/na/string.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# String helpers
|
3
4
|
class ::String
|
5
|
+
##
|
6
|
+
## Determine indentation level of line
|
7
|
+
##
|
8
|
+
## @return [Number] number of indents detected
|
9
|
+
##
|
4
10
|
def indent_level
|
5
11
|
prefix = match(/(^[ \t]+)/)
|
6
12
|
return 0 if prefix.nil?
|
@@ -11,7 +17,13 @@ class ::String
|
|
11
17
|
##
|
12
18
|
## Colorize @tags with ANSI escapes
|
13
19
|
##
|
14
|
-
## @param color
|
20
|
+
## @param color [String] color (see #Color)
|
21
|
+
## @param value [String] The value color
|
22
|
+
## template
|
23
|
+
## @param parens [String] The parens color
|
24
|
+
## template
|
25
|
+
## @param last_color [String] Color to restore after
|
26
|
+
## tag highlight
|
15
27
|
##
|
16
28
|
## @return [String] string with @tags highlighted
|
17
29
|
##
|
@@ -23,6 +35,16 @@ class ::String
|
|
23
35
|
"\\1#{tag_color}\\2#{paren_color}\\3#{value_color}\\4#{paren_color}\\5#{last_color}")
|
24
36
|
end
|
25
37
|
|
38
|
+
##
|
39
|
+
## Highlight search results
|
40
|
+
##
|
41
|
+
## @param regexes [Array] The regexes for the
|
42
|
+
## search
|
43
|
+
## @param color [String] The highlight color
|
44
|
+
## template
|
45
|
+
## @param last_color [String] Color to restore after
|
46
|
+
## highlight
|
47
|
+
##
|
26
48
|
def highlight_search(regexes, color: '{y}', last_color: '{xg}')
|
27
49
|
string = dup
|
28
50
|
color = NA::Color.template(color)
|
@@ -42,12 +64,13 @@ class ::String
|
|
42
64
|
|
43
65
|
# Returns the last escape sequence from a string.
|
44
66
|
#
|
45
|
-
# Actually returns all escape codes, with the
|
46
|
-
# that the result of inserting them
|
47
|
-
# same color as was set at
|
48
|
-
# Because you can send
|
49
|
-
#
|
50
|
-
#
|
67
|
+
# @note Actually returns all escape codes, with the
|
68
|
+
# assumption that the result of inserting them
|
69
|
+
# will generate the same color as was set at
|
70
|
+
# the end of the string. Because you can send
|
71
|
+
# modifiers like dark and bold separate from
|
72
|
+
# color codes, only using the last code may
|
73
|
+
# not render the same style.
|
51
74
|
#
|
52
75
|
# @return [String] All escape codes in string
|
53
76
|
#
|
@@ -55,8 +78,18 @@ class ::String
|
|
55
78
|
scan(/\e\[[\d;]+m/).join('').gsub(/\e\[0m/, '')
|
56
79
|
end
|
57
80
|
|
81
|
+
##
|
82
|
+
## Convert a directory path to a regular expression
|
83
|
+
##
|
84
|
+
## @note Splits at / or :, adds variable distance
|
85
|
+
## between characters, joins segments with
|
86
|
+
## slashes and requires that last segment
|
87
|
+
## match last segment of target path
|
88
|
+
##
|
89
|
+
## @param distance The distance
|
90
|
+
##
|
58
91
|
def dir_to_rx(distance: 2)
|
59
|
-
"#{split(%r{[/:]}).map { |comp| comp.split('').join(".{0,#{distance}}") }.join('.*?/.*?')}[^/]
|
92
|
+
"#{split(%r{[/:]}).map { |comp| comp.split('').join(".{0,#{distance}}").gsub(/\*/, '[^ ]*?') }.join('.*?/.*?')}[^/]*?$"
|
60
93
|
end
|
61
94
|
|
62
95
|
def dir_matches(any: [], all: [])
|
@@ -67,6 +100,11 @@ class ::String
|
|
67
100
|
matches_any(any) && matches_all(all) && matches_none(none)
|
68
101
|
end
|
69
102
|
|
103
|
+
##
|
104
|
+
## Convert wildcard characters to regular expressions
|
105
|
+
##
|
106
|
+
## @return [String] Regex string
|
107
|
+
##
|
70
108
|
def wildcard_to_rx
|
71
109
|
gsub(/\./, '\\.').gsub(/\*/, '[^ ]*?').gsub(/\?/, '.')
|
72
110
|
end
|
@@ -75,6 +113,12 @@ class ::String
|
|
75
113
|
replace cap_first
|
76
114
|
end
|
77
115
|
|
116
|
+
##
|
117
|
+
## Capitalize first character, leaving other
|
118
|
+
## capitalization in place
|
119
|
+
##
|
120
|
+
## @return [String] capitalized string
|
121
|
+
##
|
78
122
|
def cap_first
|
79
123
|
sub(/^([a-z])(.*)$/) do
|
80
124
|
m = Regexp.last_match
|
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.1.
|
12
|
+
The current version of `na` is <!--VER-->1.1.21<!--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
|
|
@@ -92,9 +92,9 @@ Unless `--exact` is specified, search is tokenized and combined with AND, so `na
|
|
92
92
|
|
93
93
|
Examples:
|
94
94
|
|
95
|
-
- `na
|
96
|
-
- `na
|
97
|
-
- `na
|
95
|
+
- `na next` (list all next actions in the current directory)
|
96
|
+
- `na next -d 3` (list all next actions in the current directory and look for additional files 3 levels deep from there)
|
97
|
+
- `na next marked2` (show next actions from another directory you've previously used na on)
|
98
98
|
|
99
99
|
```
|
100
100
|
@cli(bundle exec bin/na help next)
|