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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0430897c007446c9ad1a1e3463ddc3d8e192a43e8d60a46a9669745086ea45f3'
4
- data.tar.gz: e33799f49bbaf623d188c64f549e71dcea41b317b95b3b5d0f72f8a378a3f9fd
3
+ metadata.gz: 584d55c84c26fddeb65bf537b4743b5cac4308f39d796d336d95c900fc966deb
4
+ data.tar.gz: 73ea4289a1e43ce0b67f66f803a0db07359fe3f077358328a58c172c06daa107
5
5
  SHA512:
6
- metadata.gz: d8c9a03b08abf20cb826e452ad75478b0f58dc0309ce51bee29e3b31b6c37de8e99cdd22926aef1ffe10183b151b54b6047196ce5c8987c32b0fa013942d5673
7
- data.tar.gz: 7bb18376e8b53aa2c283206058c48dce786576d3a50d6e9567a0958011cab7f2f7203fecf0142cc49f3d5abc49a0342a4a3c20ff19318f79ac2d26ca00af206b
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- na (1.1.21)
4
+ na (1.1.22)
5
5
  chronic (~> 0.10, >= 0.10.2)
6
6
  gli (~> 2.21.0)
7
7
  tty-reader (~> 0.9, >= 0.9.0)
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.21
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.21
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 show` (list all next actions in the current directory)
213
- - `na show -d 3` (list all next actions in the current directory and look for additional files 3 levels deep from there)
214
- - `na show marked2` (show next actions from another directory you've previously used na on)
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 "Next actions are actions which contain the next action tag (default @na),
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
- m = arg.match(/^(?<req>\+)?(?<tok>.*?)$/)
97
- tokens.push({
98
- token: m['tok'],
99
- required: !m['req'].nil?
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
- token: options[:in],
297
- required: true
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
- token: options[:in],
378
- required: true
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
- m = arg.match(/^(?<req>\+)?(?<tok>.*?)$/)
473
- tokens.push({
474
- token: m['tok'],
475
- required: !m['req'].nil?
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
 
@@ -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
- NA.notify("{bw}Directory regex: {x}#{required.map(&:dir_to_rx)}", debug: true)
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 [String] color (see #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 assumption
46
- # that the result of inserting them will generate the
47
- # same color as was set at the end of the string.
48
- # Because you can send modifiers like dark and bold
49
- # separate from color codes, only using the last code
50
- # may not render the same style.
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
@@ -1,3 +1,3 @@
1
1
  module Na
2
- VERSION = '1.1.21'
2
+ VERSION = '1.1.22'
3
3
  end
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.20<!--END VER-->.
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 show` (list all next actions in the current directory)
96
- - `na show -d 3` (list all next actions in the current directory and look for additional files 3 levels deep from there)
97
- - `na show marked2` (show next actions from another directory you've previously used na on)
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)
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.1.21
4
+ version: 1.1.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra