na 1.2.40 → 1.2.43

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: 2039d6fb16db44b000517f1f19d0928c5b82124abfe1c5416f98b892f21d88da
4
- data.tar.gz: a21cd96adf698afdbf0ffd55eb43ae9c408c46cbcbec691aeb9d1052f1a55862
3
+ metadata.gz: 04412e8d8032341b954bd7cf3cd576262ca9598ba426e186bf5115183d664ce2
4
+ data.tar.gz: de6eee0c665411beaf485cd139bb8254cea08f610549bc2c94af2d89e463ab23
5
5
  SHA512:
6
- metadata.gz: a1a9e7ac7341409792174d9ecce9b00379e9fa0a53c75d01d7abf8318d7336b417aa41d1a23d5a00628a8aef9fd1f3c53070b795220b7c94b0c5d8fa12781b63
7
- data.tar.gz: 4033e29443e01ff8ee866f98255f9f2b008619d1a1f1b2e3420201a7efb99837eae612d3383234afb67c6c30fea16a1cad2199a273fd66c7d6ef21275d2aa0a5
6
+ metadata.gz: 74c57d212cbf93a6b855f81a7abb10c862febb576d39ce4389521b8c2d70a88bbd12532899eee92c814c8d12664cc4a2bb62978792d1b5f8851be465edc1bb86
7
+ data.tar.gz: e1ccd2d08d24c22aebb1d7542304f6262e8b05b75b1f567d9d6c6c234e2afe37cc306f01a97d374f73fe33cce9ab1cd1dc206b27a5be6dafd51f0e9f67657042
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ### 1.2.43
2
+
3
+ 2023-09-06 10:45
4
+
5
+ ### 1.2.42
6
+
7
+ 2023-09-06 10:32
8
+
9
+ ### 1.2.41
10
+
11
+ 2023-09-06 08:13
12
+
13
+ #### NEW
14
+
15
+ - Tag command
16
+
17
+ #### FIXED
18
+
19
+ - Nil error in action.pretty
20
+
1
21
  ### 1.2.40
2
22
 
3
23
  2023-09-06 08:11
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- na (1.2.40)
4
+ na (1.2.43)
5
5
  chronic (~> 0.10, >= 0.10.2)
6
6
  gli (~> 2.21.0)
7
7
  mdless (~> 1.0, >= 1.0.32)
@@ -13,8 +13,8 @@ GEM
13
13
  remote: https://rubygems.org/
14
14
  specs:
15
15
  chronic (0.10.2)
16
- gli (2.21.0)
17
- mdless (1.0.33)
16
+ gli (2.21.1)
17
+ mdless (1.0.35)
18
18
  minitest (5.16.3)
19
19
  rake (0.9.6)
20
20
  rdoc (4.3.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.40
12
+ The current version of `na` is 1.2.43
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.40
80
+ 1.2.43
81
81
 
82
82
  GLOBAL OPTIONS
83
83
  -a, --add - Add a next action (deprecated, for backwards compatibility)
@@ -0,0 +1,167 @@
1
+ # frozen_string_literal: true
2
+
3
+ class App
4
+ extend GLI::App
5
+ desc 'Add tags to matching action(s)'
6
+ long_desc 'Provides an easy way to tag existing actions.
7
+
8
+ Use !tag to remove a tag, use ~tag(new value) to change a tag or add a value.
9
+
10
+ If multiple todo files are found in the current directory, a menu will
11
+ allow you to pick which file to act on, or use --all to apply to all matches.'
12
+ arg_name 'TAG', mutliple: true
13
+ command %i[tag] do |c|
14
+ c.example 'na tag "project(warpspeed)" --search "An existing task"',
15
+ desc: 'Find "An existing task" action and add @project(warpspeed) to it'
16
+ c.example 'na tag "!project1" --tagged project2 --all',
17
+ desc: 'Find all actions tagged @project2 and remove @project1 from them'
18
+ c.example 'na tag "!project2" --all',
19
+ desc: 'Remove @project2 from all actions'
20
+ c.example 'na tag "~project(dirt nap)" --search "An existing task"',
21
+ desc: 'Find "An existing task" and change (or add) its @project tag value to "dirt nap"'
22
+
23
+ c.desc 'Use a known todo file, partial matches allowed'
24
+ c.arg_name 'TODO_FILE'
25
+ c.flag %i[in todo]
26
+
27
+ c.desc 'Include @done actions'
28
+ c.switch %i[done]
29
+
30
+ c.desc 'Specify the file to search for the task'
31
+ c.arg_name 'PATH'
32
+ c.flag %i[file]
33
+
34
+ c.desc 'Search for files X directories deep'
35
+ c.arg_name 'DEPTH'
36
+ c.flag %i[d depth], must_match: /^[1-9]$/, type: :integer, default_value: 1
37
+
38
+ c.desc 'Match actions containing tag. Allows value comparisons'
39
+ c.arg_name 'TAG'
40
+ c.flag %i[tagged], multiple: true
41
+
42
+ c.desc 'Act on all matches immediately (no menu)'
43
+ c.switch %i[all], negatable: false
44
+
45
+ c.desc 'Filter results using search terms'
46
+ c.arg_name 'QUERY'
47
+ c.flag %i[search find grep], multiple: true
48
+
49
+ c.desc 'Interpret search pattern as regular expression'
50
+ c.switch %i[e regex], negatable: false
51
+
52
+ c.desc 'Match pattern exactly'
53
+ c.switch %i[x exact], negatable: false
54
+
55
+ c.action do |global_options, options, args|
56
+ tags = args.join(',').split(/ *, */)
57
+ options[:remove] = []
58
+ options[:tag] = []
59
+ tags.each do |tag|
60
+ if tag =~ /^[!-]/
61
+ options[:remove] << tag.sub(/^[!-]/, '').sub(/^@/, '')
62
+ elsif tag =~ /^~/
63
+ options[:remove] << tag.sub(/^~/, '').sub(/\(.*?\)$/, '').sub(/^@/, '')
64
+ options[:tag] << tag.sub(/^~/, '').sub(/^@/, '')
65
+ else
66
+ options[:tag] << tag.sub(/^@/, '')
67
+ end
68
+ end
69
+
70
+ if options[:search]
71
+ tokens = nil
72
+ if options[:exact]
73
+ tokens = options[:search]
74
+ elsif options[:regex]
75
+ tokens = Regexp.new(options[:search], Regexp::IGNORECASE)
76
+ else
77
+ action = options[:search].join(' ')
78
+ tokens = []
79
+ all_req = action !~ /[+!-]/ && !options[:or]
80
+
81
+ action.split(/ /).each do |arg|
82
+ m = arg.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
83
+ tokens.push({
84
+ token: m['tok'],
85
+ required: all_req || (!m['req'].nil? && m['req'] == '+'),
86
+ negate: !m['req'].nil? && m['req'] =~ /[!-]/ ? true : false
87
+ })
88
+ end
89
+ end
90
+ end
91
+
92
+ if (tokens.nil? || tokens.empty?) && options[:tagged].empty?
93
+ NA.notify("#{NA.theme[:error]}Empty input, cancelled", exit_code: 1)
94
+ end
95
+
96
+ all_req = options[:tagged].join(' ') !~ /[+!-]/ && !options[:or]
97
+ tags = []
98
+ options[:tagged].join(',').split(/ *, */).each do |arg|
99
+ m = arg.match(/^(?<req>[+!-])?(?<tag>[^ =<>$~\^]+?) *(?:(?<op>[=<>~]{1,2}|[*$\^]=) *(?<val>.*?))?$/)
100
+
101
+ tags.push({
102
+ tag: m['tag'].wildcard_to_rx,
103
+ comp: m['op'],
104
+ value: m['val'],
105
+ required: all_req || (!m['req'].nil? && m['req'] == '+'),
106
+ negate: !m['req'].nil? && m['req'] =~ /[!-]/ ? true : false
107
+ })
108
+ end
109
+
110
+ add_tags = options[:tag] ? options[:tag].join(',').split(/ *, */).map { |t| t.sub(/^@/, '').wildcard_to_rx } : []
111
+ remove_tags = options[:remove] ? options[:remove].join(',').split(/ *, */).map { |t| t.sub(/^@/, '').wildcard_to_rx } : []
112
+
113
+ if options[:file]
114
+ file = File.expand_path(options[:file])
115
+ NA.notify("#{NA.theme[:error]}File not found", exit_code: 1) unless File.exist?(file)
116
+
117
+ targets = [file]
118
+ elsif options[:todo]
119
+ todo = []
120
+ options[:todo].split(/ *, */).each do |a|
121
+ m = a.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
122
+ todo.push({
123
+ token: m['tok'],
124
+ required: all_req || (!m['req'].nil? && m['req'] == '+'),
125
+ negate: !m['req'].nil? && m['req'] =~ /[!-]/ ? true : false
126
+ })
127
+ end
128
+ dirs = NA.match_working_dir(todo)
129
+
130
+ if dirs.count == 1
131
+ targets = [dirs[0]]
132
+ elsif dirs.count.positive?
133
+ targets = NA.select_file(dirs, multiple: true)
134
+ NA.notify("#{NA.theme[:error]}Cancelled", exit_code: 1) unless targets && targets.count.positive?
135
+ else
136
+ NA.notify("#{NA.theme[:error]}Todo not found", exit_code: 1) unless targets && targets.count.positive?
137
+
138
+ end
139
+ else
140
+ files = NA.find_files_matching({
141
+ depth: options[:depth],
142
+ done: options[:done],
143
+ regex: options[:regex],
144
+ require_na: false,
145
+ search: tokens,
146
+ tag: tags
147
+ })
148
+ NA.notify("#{NA.theme[:error]}No todo file found", exit_code: 1) if files.count.zero?
149
+
150
+ targets = files.count > 1 ? NA.select_file(files, multiple: true) : [files[0]]
151
+ NA.notify("#{NA.theme[:error]}Cancelled", exit_code: 1) unless files.count.positive?
152
+
153
+ end
154
+
155
+ NA.notify("#{NA.theme[:error]}No search terms provided", exit_code: 1) if tokens.nil? && options[:tagged].empty?
156
+
157
+ targets.each do |target|
158
+ NA.update_action(target, tokens,
159
+ add_tag: add_tags,
160
+ all: options[:all],
161
+ done: options[:done],
162
+ remove_tag: remove_tags,
163
+ tagged: tags)
164
+ end
165
+ end
166
+ end
167
+ end
data/lib/na/action.rb CHANGED
@@ -110,13 +110,13 @@ module NA
110
110
 
111
111
  if detect_width
112
112
  width = TTY::Screen.columns
113
- prefix = NA::Color.uncolor(pretty(template: { output: template[:templates][:output].sub(/%action/, '') }, detect_width: false))
113
+ prefix = NA::Color.uncolor(pretty(template: { templates: { output: template[:templates][:output].sub(/%action/, '') } }, detect_width: false))
114
114
  indent = prefix.length
115
115
  action = action.wrap(width, indent)
116
116
  end
117
117
 
118
118
  # Replace variables in template string and output colorized
119
- NA::Color.template(template[:output].gsub(/%filename/, filename)
119
+ NA::Color.template(template[:templates][:output].gsub(/%filename/, filename)
120
120
  .gsub(/%project/, project)
121
121
  .gsub(/%parents?/, parents)
122
122
  .gsub(/%action/, action.highlight_search(regexes))
data/lib/na/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Na
2
- VERSION = '1.2.40'
2
+ VERSION = '1.2.43'
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.2.39<!--END VER-->.
12
+ The current version of `na` is <!--VER-->1.2.41<!--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
 
data/test2.txt ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ comment: 2023
3
+ keywords:
4
+ ---
5
+
6
+ Inbox:
7
+ - Test @na
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.40
4
+ version: 1.2.43
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
@@ -220,6 +220,7 @@ files:
220
220
  - bin/commands/prompt.rb
221
221
  - bin/commands/restore.rb
222
222
  - bin/commands/saved.rb
223
+ - bin/commands/tag.rb
223
224
  - bin/commands/tagged.rb
224
225
  - bin/commands/todos.rb
225
226
  - bin/commands/undo.rb
@@ -245,6 +246,7 @@ files:
245
246
  - na.rdoc
246
247
  - scripts/fixreadme.rb
247
248
  - src/_README.md
249
+ - test2.txt
248
250
  homepage: https://brettterpstra.com/projects/na/
249
251
  licenses:
250
252
  - MIT
@@ -271,7 +273,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
271
273
  - !ruby/object:Gem::Version
272
274
  version: '0'
273
275
  requirements: []
274
- rubygems_version: 3.2.16
276
+ rubygems_version: 3.4.0.dev
275
277
  signing_key:
276
278
  specification_version: 4
277
279
  summary: A command line tool for adding and listing project todos