na 1.2.100 → 1.2.102

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: 161cff6e82e373cadc9394d29ff0f85370bbf5534e670e92932967d2a0c0b84f
4
- data.tar.gz: a12760bc81615804c838e1307d8f2a36540773029d8fe46fab009343c8d4edf8
3
+ metadata.gz: 3e4ec9be9bb02df547b4d80dda0e81ccf1e33ab1eb31032e49f21012c9cffa1e
4
+ data.tar.gz: f3229716b013fd13fe48b03586df9bfd2d9cc07925b69c9d72882025a05fe39b
5
5
  SHA512:
6
- metadata.gz: 2a99a7da6f5bf56c317e97096fdd76b5e6001acf4008f82b8b3fd7e16c3063b15f89c96d32bbab9a630fa221620fb81cba4a48ab1f0ce94e4deb40ad0680049f
7
- data.tar.gz: 3347cdfe0edb74a52434cb6efd54a7128f27186f50cf281ca70c112864d49224c4d8b72558058451cb60d25b15613fd117ba5e697c5c5f0eddb9f354d9919021
6
+ metadata.gz: 0c56a1b6466fbef64e67b09cb11833cc74fbd487f5fdf78173ba092aa0efba062825988db6d60784ddafbc78fd5aefea6a8db77735e162f4620ba80b04ac0a27
7
+ data.tar.gz: 1b5ba39b700810493e09e684d693cef30a9eb7056e7a4b131afbd4b626cc022a03492272645690b160ab39238ef4921c281acaac57210a0cd66c706d4d2464a8
data/CHANGELOG.md CHANGED
@@ -1,3 +1,41 @@
1
+ ### 1.2.102
2
+
3
+ 2026-04-27 04:36
4
+
5
+ #### CHANGED
6
+
7
+ - Allow next --available with filters to match actions without the default @na tag.
8
+ - Bump the gem version to 1.2.101.
9
+ - Bump the gem version to 1.2.102.
10
+
11
+ #### NEW
12
+
13
+ - Add next --available/-a to show the first available action per project.
14
+
15
+ #### FIXED
16
+
17
+ - Match unique nested projects by leaf name in add/update
18
+ - Make --color force colored output even when stdout is not a TTY.
19
+ - Make -f FILE --color force colored output when stdout is not a TTY.
20
+
21
+ ### 1.2.101
22
+
23
+ 2026-04-26 12:06
24
+
25
+ #### CHANGED
26
+
27
+ - Allow next --available with filters to match actions without the default @na tag.
28
+ - Bump the gem version to 1.2.101.
29
+
30
+ #### NEW
31
+
32
+ - Add next --available/-a to show the first available action per project.
33
+
34
+ #### FIXED
35
+
36
+ - Match unique nested projects by leaf name in add/update
37
+ - Make --color force colored output even when stdout is not a TTY.
38
+
1
39
  ### 1.2.100
2
40
 
3
41
  2026-02-27 09:53
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- na (1.2.100)
4
+ na (1.2.102)
5
5
  chronic (~> 0.10, >= 0.10.2)
6
6
  csv (~> 3.2)
7
7
  git (~> 3.0.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.2.100.
12
+ The current version of `na` is 1.2.102.
13
13
 
14
14
 
15
15
  ### Table of contents
@@ -257,7 +257,7 @@ SYNOPSIS
257
257
  na [global options] command [command options] [arguments...]
258
258
 
259
259
  VERSION
260
- 1.2.100
260
+ 1.2.102
261
261
 
262
262
  GLOBAL OPTIONS
263
263
  -a, --add - Add a next action (deprecated, for backwards compatibility)
@@ -522,6 +522,7 @@ DESCRIPTION
522
522
  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).
523
523
 
524
524
  COMMAND OPTIONS
525
+ -a, --available - Show only the first available action per project
525
526
  --all - Show next actions from all known todo files (in any directory)
526
527
  -d, --depth=DEPTH - Recurse to depth (default: none)
527
528
  --divider=STRING - Divider string for text IO (default: none)
data/bin/commands/next.rb CHANGED
@@ -25,6 +25,9 @@ class App
25
25
  c.desc "Show next actions from all known todo files (in any directory)"
26
26
  c.switch %i[all], negatable: false, default_value: false
27
27
 
28
+ c.desc "Show only the first available action per project"
29
+ c.switch %i[a available], negatable: false
30
+
28
31
  c.desc "Display matches from a known todo file anywhere in history (short name)"
29
32
  c.arg_name "TODO"
30
33
  c.flag %i[in todo], multiple: true
@@ -169,6 +172,8 @@ class App
169
172
  next
170
173
  end
171
174
 
175
+ available = options[:available]
176
+
172
177
  if options[:exact] || options[:regex]
173
178
  search = options[:search].join(" ")
174
179
  else
@@ -288,9 +293,22 @@ class App
288
293
  end
289
294
 
290
295
  NA.na_tag = options[:tag] unless options[:tag].nil?
291
- require_na = true
292
296
 
293
- tag = [{ tag: NA.na_tag, value: nil, required: true, negate: false }]
297
+ # When -a/--available is combined with --all or any filtering flags,
298
+ # relax the implicit NA_TAG requirement and show the first available
299
+ # action that matches the filters instead.
300
+ filtered_mode = options[:all] ||
301
+ options[:save] ||
302
+ !options[:tag].nil? ||
303
+ options[:project] ||
304
+ options[:tagged].any? ||
305
+ options[:priority].any? ||
306
+ (options[:search].respond_to?(:any?) && options[:search].any?)
307
+
308
+ require_na = !(available && filtered_mode)
309
+
310
+ tag = []
311
+ tag << { tag: NA.na_tag, value: nil, required: true, negate: false } if require_na
294
312
  tag << { tag: "done", value: nil, negate: true } unless options[:done]
295
313
  tag.concat(tags)
296
314
 
@@ -378,17 +396,24 @@ class App
378
396
  end
379
397
  end
380
398
  end
381
- todo.actions.output(depth,
382
- { files: todo.files,
383
- nest: options[:nest],
384
- nest_projects: options[:omnifocus],
385
- notes: options[:notes],
386
- no_files: options[:no_file],
387
- times: options[:times],
388
- human: options[:human],
389
- only_timed: options[:only_timed],
390
- json_times: options[:json_times],
391
- only_times: options[:only_times] })
399
+
400
+ actions = if available
401
+ todo.actions.first_available_per_project(require_na: require_na)
402
+ else
403
+ todo.actions
404
+ end
405
+
406
+ actions.output(depth,
407
+ { files: todo.files,
408
+ nest: options[:nest],
409
+ nest_projects: options[:omnifocus],
410
+ notes: options[:notes],
411
+ no_files: options[:no_file],
412
+ times: options[:times],
413
+ human: options[:human],
414
+ only_timed: options[:only_timed],
415
+ json_times: options[:json_times],
416
+ only_times: options[:only_times] })
392
417
  end
393
418
  end
394
419
  end
data/bin/na CHANGED
@@ -9,6 +9,8 @@ require 'na/benchmark'
9
9
  require 'fcntl'
10
10
  require 'tempfile'
11
11
 
12
+ ORIGINAL_ARGV = ARGV.dup
13
+
12
14
  NA::Benchmark.init
13
15
  NA::Benchmark.measure('Gem loading') { nil } # Measures time up to this point
14
16
 
@@ -116,7 +118,7 @@ class App
116
118
  NA::Plugins.ensure_plugins_home
117
119
  NA.verbose = global[:debug]
118
120
  NA::Pager.paginate = global[:pager] && $stdout.isatty
119
- NA::Color.coloring = global[:color] && $stdout.isatty
121
+ NA::Color.coloring = global[:color] && ($stdout.isatty || ORIGINAL_ARGV.include?('--color'))
120
122
  NA.extension = global[:ext]
121
123
  NA.include_ext = global[:include_ext]
122
124
  NA.na_tag = global[:na_tag]
@@ -175,7 +177,7 @@ class App
175
177
  on_error do |exception|
176
178
  case exception
177
179
  when GLI::UnknownCommand
178
- if NA.command_line.count == 1
180
+ if NA.command_line.one?
179
181
  cmd = ['saved']
180
182
  cmd.concat(ARGV.unshift(NA.command_line[0]))
181
183
 
data/lib/na/actions.rb CHANGED
@@ -7,6 +7,30 @@ module NA
7
7
  super
8
8
  end
9
9
 
10
+ # Return the first available action per project path.
11
+ #
12
+ # @param require_na [Boolean] If true, only consider actions with the NA tag
13
+ # @return [NA::Actions] A new Actions collection with at most one action per project
14
+ def first_available_per_project(require_na: true)
15
+ NA::Benchmark.measure('Actions.first_available_per_project') do
16
+ seen = {}
17
+ selected = NA::Actions.new
18
+
19
+ each do |action|
20
+ next if require_na && !action.respond_to?(:na?) ? false : (require_na && !action.na?)
21
+
22
+ project_path = Array(action.parent).join(':')
23
+ next if project_path.empty?
24
+ next if seen.key?(project_path)
25
+
26
+ seen[project_path] = true
27
+ selected << action
28
+ end
29
+
30
+ selected
31
+ end
32
+ end
33
+
10
34
  # Pretty print a list of actions
11
35
  #
12
36
  # @param depth [Integer] The depth of the action
data/lib/na/version.rb CHANGED
@@ -5,5 +5,5 @@
5
5
  module Na
6
6
  ##
7
7
  # Current version of the na gem.
8
- VERSION = '1.2.100'
8
+ VERSION = '1.2.102'
9
9
  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.2.98<!--END VER-->.
12
+ The current version of `na` is <!--VER-->1.2.101<!--END VER-->.
13
13
 
14
14
  <!--GITHUB-->
15
15
  ### Table of contents
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.100
4
+ version: 1.2.102
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
@@ -360,7 +360,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
360
360
  - !ruby/object:Gem::Version
361
361
  version: '0'
362
362
  requirements: []
363
- rubygems_version: 4.0.3
363
+ rubygems_version: 3.6.7
364
364
  specification_version: 4
365
365
  summary: A command line tool for adding and listing project todos
366
366
  test_files: []