na 1.2.77 → 1.2.79

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: 63fd25bab893e0b4deef2d7bd4f3df057e6cefe7a68c25edb2e7034c590220d0
4
- data.tar.gz: 93e92eac54211939b57b2fefb63643aca1c348d1e6f6a96cabb049d3d8aedb7b
3
+ metadata.gz: 482bb5668dec4d69c1a9fc41340f723589724730fb930ff9f45d5bbaa5bd3dd3
4
+ data.tar.gz: fa3cd141c8cf0a7ad41d52f399e9f400bd35708112d3ce9cab6bf2b7795a96b1
5
5
  SHA512:
6
- metadata.gz: 2f008ca3f8f239dc791571809e4e1eda53c7f6bb7b107d774a6805f42bc72e55eb1da7e4da3481c8c4ab21332e15d0b13b1b7d1defe61d9bac19267e05eb443d
7
- data.tar.gz: 532e38bdc9ea8ecb917f9e0ae5faacb0c77bf206269cf08c968716dc766407426eceb8006aef2fbf66dab925cab48889b59413f3aabffd2825f66f6617ac7e62
6
+ metadata.gz: a58d99161596166ce0b0ae34b45a35bcd86239e3606b05ec1431aed999f693475391a2e21ea3a7fdfb80bcf8d88ef2c3bcd3d20daaf34e474b2ab561d5051358
7
+ data.tar.gz: 02f36b28b78d5fae3144450a34bb910c22a6097dc13512b12e35bbc34d290a2f085500865bba4f2514e55692d9d862ec26854662eb438557e2d8a50473f511e6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ ### 1.2.79
2
+
3
+ 2025-09-29 06:51
4
+
5
+ #### NEW
6
+
7
+ - Track affected actions in `update_action` and output per-action summaries
8
+
9
+ #### IMPROVED
10
+
11
+ - Prompt to select a project when multiple suffix matches are found
12
+ - Distinguish summaries: Task deleted vs Task updated/added
13
+ - Display affected actions using `action.to_s_pretty` with colored change descriptions
14
+
15
+ #### FIXED
16
+
17
+ - Resolve project matching for `na add --to Ideas` by supporting unique suffix matches (e.g. `rnkd:Ideas`)
18
+ - Validate `na update` requires at least one actionable option; error with No action specified, see `na help update`
19
+
20
+ ### 1.2.78
21
+
22
+ 2025-06-02 10:07
23
+
24
+ #### FIXED
25
+
26
+ - Strip! error on `update -p`
27
+
1
28
  ### 1.2.77
2
29
 
3
30
  2025-05-10 12:10
data/Gemfile.lock CHANGED
@@ -1,11 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- na (1.2.77)
4
+ na (1.2.79)
5
5
  chronic (~> 0.10, >= 0.10.2)
6
6
  git (~> 3.0.0)
7
7
  gli (~> 2.21.0)
8
8
  mdless (~> 1.0, >= 1.0.32)
9
+ ostruct (~> 0.6, >= 0.6.1)
9
10
  tty-reader (~> 0.9, >= 0.9.0)
10
11
  tty-screen (~> 0.8, >= 0.8.1)
11
12
  tty-which (~> 0.5, >= 0.5.0)
@@ -28,14 +29,14 @@ GEM
28
29
  uri (>= 0.13.1)
29
30
  addressable (2.8.7)
30
31
  public_suffix (>= 2.0.2, < 7.0)
31
- base64 (0.2.0)
32
- benchmark (0.4.0)
33
- bigdecimal (3.1.9)
32
+ base64 (0.3.0)
33
+ benchmark (0.4.1)
34
+ bigdecimal (3.2.1)
34
35
  chronic (0.10.2)
35
36
  concurrent-ruby (1.3.5)
36
- connection_pool (2.5.1)
37
- drb (2.2.1)
38
- git (3.0.0)
37
+ connection_pool (2.5.3)
38
+ drb (2.2.3)
39
+ git (3.0.2)
39
40
  activesupport (>= 5.0)
40
41
  addressable (~> 2.8)
41
42
  process_executer (~> 1.3)
@@ -43,12 +44,13 @@ GEM
43
44
  gli (2.21.5)
44
45
  i18n (1.14.7)
45
46
  concurrent-ruby (~> 1.0)
46
- logger (1.6.6)
47
+ logger (1.7.0)
47
48
  mdless (1.0.37)
48
49
  minitest (5.25.5)
50
+ ostruct (0.6.1)
49
51
  process_executer (1.3.0)
50
- public_suffix (6.0.1)
51
- rake (13.2.1)
52
+ public_suffix (6.0.2)
53
+ rake (13.3.0)
52
54
  rchardet (1.9.0)
53
55
  rdoc (4.3.0)
54
56
  securerandom (0.4.1)
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.77.
12
+ The current version of `na` is 1.2.79.
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
 
@@ -76,7 +76,7 @@ SYNOPSIS
76
76
  na [global options] command [command options] [arguments...]
77
77
 
78
78
  VERSION
79
- 1.2.77
79
+ 1.2.79
80
80
 
81
81
  GLOBAL OPTIONS
82
82
  -a, --add - Add a next action (deprecated, for backwards compatibility)
@@ -189,6 +189,23 @@ class App
189
189
  note = stdin_note.empty? ? [] : stdin_note
190
190
  note.concat(line_note) unless line_note.nil? || line_note.empty?
191
191
 
192
+ # Require at least one actionable option to be provided
193
+ actionable = [
194
+ options[:note],
195
+ (options[:priority].to_i if options[:priority]).to_i > 0,
196
+ !options[:move].to_s.empty?,
197
+ !(options[:tag].nil? || options[:tag].empty?),
198
+ !(options[:remove].nil? || options[:remove].empty?),
199
+ !options[:replace].to_s.empty?,
200
+ options[:finish],
201
+ options[:archive],
202
+ options[:restore],
203
+ options[:delete],
204
+ options[:edit]
205
+ ].any?
206
+
207
+ NA.notify("#{NA.theme[:error]}No action specified, see `na help update`", exit_code: 1) unless actionable
208
+
192
209
  target_proj = if options[:move]
193
210
  options[:move]
194
211
  elsif NA.cwd_is == :project
data/lib/na/action.rb CHANGED
@@ -22,7 +22,8 @@ module NA
22
22
  string = @action.dup
23
23
 
24
24
  if priority&.positive?
25
- string.gsub!(/(?<=\A| )@priority\(\d+\)/, '').strip!
25
+ string.gsub!(/(?<=\A| )@priority\(\d+\)/, '')
26
+ string.strip!
26
27
  string += " @priority(#{priority})"
27
28
  end
28
29
 
@@ -52,6 +53,15 @@ module NA
52
53
  "(#{@file}:#{@line}) #{@project}:#{@parent.join('>')} | #{@action}#{note}"
53
54
  end
54
55
 
56
+ def to_s_pretty
57
+ note = if @note.count.positive?
58
+ "\n#{@note.join("\n")}"
59
+ else
60
+ ''
61
+ end
62
+ "#{NA.theme[:filename]}#{File.basename(@file)}:#{@line}#{NA.theme[:bracket]}[#{NA.theme[:project]}#{@project}:#{@parent.join(">")}#{NA.theme[:bracket]}]{x} | #{NA.theme[:action]}#{@action}#{NA.theme[:note]}#{note}"
63
+ end
64
+
55
65
  def inspect
56
66
  <<~EOINSPECT
57
67
  @file: #{@file}
@@ -259,6 +259,7 @@ module NA
259
259
  tagged: nil)
260
260
 
261
261
  projects = find_projects(target)
262
+ affected_actions = []
262
263
 
263
264
  target_proj = nil
264
265
 
@@ -287,9 +288,22 @@ module NA
287
288
  target_proj = if target_proj
288
289
  projects.select { |proj| proj.project =~ /^#{target_proj.project}$/i }.first
289
290
  else
291
+ # First try exact full-path match
290
292
  projects.select { |proj| proj.project =~ /^#{add.parent.join(':')}$/i }.first
291
293
  end
292
294
 
295
+ # If no exact match, try unique suffix match (e.g., :Ideas at end)
296
+ if target_proj.nil?
297
+ leaf = Regexp.escape(add.parent.join(':'))
298
+ suffix_matches = projects.select { |proj| proj.project =~ /(^|:)#{leaf}$/i }
299
+ if suffix_matches.count == 1
300
+ target_proj = suffix_matches.first
301
+ elsif suffix_matches.count > 1 && $stdout.isatty
302
+ choice = choose_from(suffix_matches.map(&:project), prompt: 'Select a target project: ', multiple: false)
303
+ target_proj = projects.select { |proj| proj.project == choice }.first if choice
304
+ end
305
+ end
306
+
293
307
  if target_proj.nil?
294
308
  res = NA.yn(NA::Color.template("#{NA.theme[:warning]}Project #{NA.theme[:file]}#{add.project}#{NA.theme[:warning]} doesn't exist, add it"), default: true)
295
309
 
@@ -336,6 +350,15 @@ module NA
336
350
  contents.insert(target_line, "#{indent}\t- #{add.action}#{note}")
337
351
 
338
352
  notify(add.pretty)
353
+
354
+ # Track affected action and description
355
+ changes = ["added"]
356
+ changes << "finished" if finish
357
+ changes << "priority=#{priority}" if priority.to_i.positive?
358
+ changes << "tags+#{add_tag.join(',')}" unless add_tag.nil? || add_tag.empty?
359
+ changes << "tags-#{remove_tag.join(',')}" unless remove_tag.nil? || remove_tag.empty?
360
+ changes << "note updated" unless note.nil? || note.empty?
361
+ affected_actions << { action: add, desc: changes.join(', ') }
339
362
  else
340
363
  _, actions = find_actions(target, search, tagged, done: done, all: all, project: project, search_note: search_note)
341
364
 
@@ -343,7 +366,11 @@ module NA
343
366
 
344
367
  actions.sort_by(&:line).reverse.each do |action|
345
368
  contents.slice!(action.line, action.note.count + 1)
346
- next if delete
369
+ if delete
370
+ # Track deletion before skipping re-insert
371
+ affected_actions << { action: action, desc: 'deleted' }
372
+ next
373
+ end
347
374
 
348
375
  projects = shift_index_after(projects, action.line, action.note.count + 1)
349
376
 
@@ -395,16 +422,44 @@ module NA
395
422
  contents.insert(target_line, "#{indent}\t- #{action.action}#{note}")
396
423
 
397
424
  notify(action.pretty)
425
+
426
+ # Track affected action and description
427
+ changes = []
428
+ changes << "finished" if finish
429
+ changes << "edited" if edit
430
+ changes << "priority=#{priority}" if priority.to_i.positive?
431
+ changes << "tags+#{add_tag.join(',')}" unless add_tag.nil? || add_tag.empty?
432
+ changes << "tags-#{remove_tag.join(',')}" unless remove_tag.nil? || remove_tag.empty?
433
+ changes << "text replaced" if replace
434
+ changes << "moved to #{target_proj.project}" if target_proj
435
+ changes << "note updated" unless note.nil? || note.empty?
436
+ changes = ["updated"] if changes.empty?
437
+ affected_actions << { action: action, desc: changes.join(', ') }
398
438
  end
399
439
  end
400
440
 
401
441
  backup_file(target)
402
442
  File.open(target, 'w') { |f| f.puts contents.join("\n") }
403
443
 
404
- if add
405
- notify("#{NA.theme[:success]}Task added to #{NA.theme[:filename]}#{target}")
444
+ if affected_actions.any?
445
+ if affected_actions.all? { |e| e[:desc] =~ /^deleted/ }
446
+ notify("#{NA.theme[:success]}Task deleted in #{NA.theme[:filename]}#{target}")
447
+ elsif add
448
+ notify("#{NA.theme[:success]}Task added to #{NA.theme[:filename]}#{target}")
449
+ else
450
+ notify("#{NA.theme[:success]}Task updated in #{NA.theme[:filename]}#{target}")
451
+ end
452
+
453
+ affected_actions.reverse.each do |entry|
454
+ action_color = delete ? NA.theme[:error] : NA.theme[:success]
455
+ notify(" #{entry[:action].to_s_pretty} — #{action_color}#{entry[:desc]}")
456
+ end
406
457
  else
407
- notify("#{NA.theme[:success]}Task updated in #{NA.theme[:filename]}#{target}")
458
+ if add
459
+ notify("#{NA.theme[:success]}Task added to #{NA.theme[:filename]}#{target}")
460
+ else
461
+ notify("#{NA.theme[:success]}Task updated in #{NA.theme[:filename]}#{target}")
462
+ end
408
463
  end
409
464
  end
410
465
 
data/lib/na/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Na
2
- VERSION = '1.2.77'
2
+ VERSION = '1.2.79'
3
3
  end
data/na.gemspec CHANGED
@@ -30,5 +30,6 @@ spec = Gem::Specification.new do |s|
30
30
  s.add_runtime_dependency('tty-screen', '~> 0.8', '>= 0.8.1')
31
31
  s.add_runtime_dependency('tty-which', '~> 0.5', '>= 0.5.0')
32
32
  s.add_runtime_dependency('git', '~> 3.0.0')
33
+ s.add_runtime_dependency('ostruct', '~> 0.6', '>= 0.6.1')
33
34
  s.add_development_dependency('tty-spinner', '~> 0.9', '>= 0.9.0')
34
35
  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.76<!--END VER-->.
12
+ The current version of `na` is <!--VER-->1.2.78<!--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,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: na
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.77
4
+ version: 1.2.79
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-05-10 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: minitest
@@ -165,6 +165,26 @@ dependencies:
165
165
  - - "~>"
166
166
  - !ruby/object:Gem::Version
167
167
  version: 3.0.0
168
+ - !ruby/object:Gem::Dependency
169
+ name: ostruct
170
+ requirement: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - "~>"
173
+ - !ruby/object:Gem::Version
174
+ version: '0.6'
175
+ - - ">="
176
+ - !ruby/object:Gem::Version
177
+ version: 0.6.1
178
+ type: :runtime
179
+ prerelease: false
180
+ version_requirements: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - "~>"
183
+ - !ruby/object:Gem::Version
184
+ version: '0.6'
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: 0.6.1
168
188
  - !ruby/object:Gem::Dependency
169
189
  name: tty-spinner
170
190
  requirement: !ruby/object:Gem::Requirement
@@ -286,7 +306,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
286
306
  - !ruby/object:Gem::Version
287
307
  version: '0'
288
308
  requirements: []
289
- rubygems_version: 3.6.6
309
+ rubygems_version: 3.6.7
290
310
  specification_version: 4
291
311
  summary: A command line tool for adding and listing project todos
292
312
  test_files: []