na 1.2.91 → 1.2.92
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/.cursor/commands/changelog.md +2 -0
- data/.rubocop_todo.yml +10 -10
- data/CHANGELOG.md +13 -0
- data/Gemfile.lock +1 -1
- data/README.md +2 -2
- data/lib/na/action.rb +12 -12
- data/lib/na/actions.rb +2 -2
- data/lib/na/next_action.rb +34 -14
- data/lib/na/string.rb +9 -9
- data/lib/na/todo.rb +3 -3
- data/lib/na/version.rb +1 -1
- data/src/_README.md +1 -1
- 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: 34119e46896bef108bcd426961bff8809cd81ef75054984d4735a84fbe8cdc58
|
|
4
|
+
data.tar.gz: 6d9d1c2faffce4ba6d4cab6f75ccb2c3364c9ced1b9a0552097189431a5faff9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e87485d65980548a49de41456198dceef2497c3b907285da0a98def36a6836ccc5ba65c1d7457d65ff0be51157e0ba3ca06593fff0d4c57afe89db5d5f9fe2aa
|
|
7
|
+
data.tar.gz: d8b96dad65a1119ae604c2e27f876bdd7b3db7b5d0a0f4945e5cad429764823e635c2687510f3dc09cd8a7e92c55b4945666a12f597e60b2c28aee27c1e9db7a
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
Write a commmit message that uses @ labels to specify what type of change each line is. Apply @new, @fixed, @changed, @improved, and @breaking as appropriate to each line. Only add @ labels to changes that affect the user, not technical details. Technical details can be included in the commit, just don't add @ labels to those lines. Be sure to include a general description (< 60 characters) as the first line, followed by a line break.
|
|
2
2
|
|
|
3
|
+
Do not add @tags to notes about documentation updates. Always focus on actual code changes we've made since the last commit when generating the commit message.
|
|
4
|
+
|
|
3
5
|
|
|
4
6
|
Save this commit message to commit_message.txt. Overwrite existing contents.
|
|
5
7
|
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on 2025-
|
|
3
|
+
# on 2025-11-16 16:32:01 UTC using RuboCop version 1.81.7.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
@@ -15,7 +15,7 @@ Lint/DuplicateBranch:
|
|
|
15
15
|
|
|
16
16
|
# Offense count: 2
|
|
17
17
|
# This cop supports safe autocorrection (--autocorrect).
|
|
18
|
-
# Configuration parameters:
|
|
18
|
+
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
|
|
19
19
|
# NotImplementedExceptions: NotImplementedError
|
|
20
20
|
Lint/UnusedMethodArgument:
|
|
21
21
|
Exclude:
|
|
@@ -24,7 +24,7 @@ Lint/UnusedMethodArgument:
|
|
|
24
24
|
# Offense count: 49
|
|
25
25
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
|
26
26
|
Metrics/AbcSize:
|
|
27
|
-
Max:
|
|
27
|
+
Max: 309
|
|
28
28
|
|
|
29
29
|
# Offense count: 11
|
|
30
30
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
@@ -40,22 +40,22 @@ Metrics/BlockNesting:
|
|
|
40
40
|
# Offense count: 6
|
|
41
41
|
# Configuration parameters: CountComments, CountAsOne.
|
|
42
42
|
Metrics/ClassLength:
|
|
43
|
-
Max:
|
|
43
|
+
Max: 926
|
|
44
44
|
|
|
45
45
|
# Offense count: 34
|
|
46
46
|
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
|
47
47
|
Metrics/CyclomaticComplexity:
|
|
48
|
-
Max:
|
|
48
|
+
Max: 91
|
|
49
49
|
|
|
50
50
|
# Offense count: 55
|
|
51
51
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
52
52
|
Metrics/MethodLength:
|
|
53
|
-
Max:
|
|
53
|
+
Max: 202
|
|
54
54
|
|
|
55
55
|
# Offense count: 5
|
|
56
56
|
# Configuration parameters: CountComments, CountAsOne.
|
|
57
57
|
Metrics/ModuleLength:
|
|
58
|
-
Max:
|
|
58
|
+
Max: 928
|
|
59
59
|
|
|
60
60
|
# Offense count: 5
|
|
61
61
|
# Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
|
|
@@ -65,7 +65,7 @@ Metrics/ParameterLists:
|
|
|
65
65
|
# Offense count: 33
|
|
66
66
|
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
|
67
67
|
Metrics/PerceivedComplexity:
|
|
68
|
-
Max:
|
|
68
|
+
Max: 104
|
|
69
69
|
|
|
70
70
|
# Offense count: 1
|
|
71
71
|
# Configuration parameters: ForbiddenDelimiters.
|
|
@@ -118,9 +118,9 @@ Style/YAMLFileRead:
|
|
|
118
118
|
Exclude:
|
|
119
119
|
- 'lib/na/theme.rb'
|
|
120
120
|
|
|
121
|
-
# Offense count:
|
|
121
|
+
# Offense count: 28
|
|
122
122
|
# This cop supports safe autocorrection (--autocorrect).
|
|
123
|
-
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
|
|
123
|
+
# Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
|
|
124
124
|
# URISchemes: http, https
|
|
125
125
|
Layout/LineLength:
|
|
126
126
|
Max: 293
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
### 1.2.92
|
|
2
|
+
|
|
3
|
+
2025-11-16 10:32
|
|
4
|
+
|
|
5
|
+
#### NEW
|
|
6
|
+
|
|
7
|
+
- Prompt to create missing project paths when using --to.
|
|
8
|
+
|
|
9
|
+
#### FIXED
|
|
10
|
+
|
|
11
|
+
- Insert newly created project sections at the correct hierarchy depth.
|
|
12
|
+
- Display added actions with a single project path in confirmations.
|
|
13
|
+
|
|
1
14
|
### 1.2.91
|
|
2
15
|
|
|
3
16
|
2025-11-11 18:17
|
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.2.
|
|
12
|
+
The current version of `na` is 1.2.92.
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
### Table of contents
|
|
@@ -116,7 +116,7 @@ SYNOPSIS
|
|
|
116
116
|
na [global options] command [command options] [arguments...]
|
|
117
117
|
|
|
118
118
|
VERSION
|
|
119
|
-
1.2.
|
|
119
|
+
1.2.92
|
|
120
120
|
|
|
121
121
|
GLOBAL OPTIONS
|
|
122
122
|
-a, --add - Add a next action (deprecated, for backwards compatibility)
|
data/lib/na/action.rb
CHANGED
|
@@ -138,7 +138,7 @@ module NA
|
|
|
138
138
|
# @example
|
|
139
139
|
# action.to_s #=> "{ project: 'Inbox', ... }"
|
|
140
140
|
def to_s
|
|
141
|
-
note = if @note.
|
|
141
|
+
note = if @note.any?
|
|
142
142
|
"\n#{@note.join("\n")}"
|
|
143
143
|
else
|
|
144
144
|
''
|
|
@@ -150,7 +150,7 @@ module NA
|
|
|
150
150
|
#
|
|
151
151
|
# @return [String]
|
|
152
152
|
def to_s_pretty
|
|
153
|
-
note = if @note.
|
|
153
|
+
note = if @note.any?
|
|
154
154
|
"\n#{@note.join("\n")}"
|
|
155
155
|
else
|
|
156
156
|
''
|
|
@@ -302,7 +302,7 @@ module NA
|
|
|
302
302
|
# @param none [Array] Tags to match none
|
|
303
303
|
# @return [Boolean]
|
|
304
304
|
def tags_match?(any: [], all: [], none: [])
|
|
305
|
-
tag_matches_any(any) && tag_matches_all(all) && tag_matches_none(none)
|
|
305
|
+
tag_matches_any?(any) && tag_matches_all?(all) && tag_matches_none?(none)
|
|
306
306
|
end
|
|
307
307
|
|
|
308
308
|
# Check if action or note matches any, all, and none search criteria
|
|
@@ -313,9 +313,9 @@ module NA
|
|
|
313
313
|
# @param include_note [Boolean] Include note in search
|
|
314
314
|
# @return [Boolean]
|
|
315
315
|
def search_match?(any: [], all: [], none: [], include_note: true)
|
|
316
|
-
search_matches_any(any, include_note: include_note) &&
|
|
317
|
-
search_matches_all(all, include_note: include_note) &&
|
|
318
|
-
search_matches_none(none, include_note: include_note)
|
|
316
|
+
search_matches_any?(any, include_note: include_note) &&
|
|
317
|
+
search_matches_all?(all, include_note: include_note) &&
|
|
318
|
+
search_matches_none?(none, include_note: include_note)
|
|
319
319
|
end
|
|
320
320
|
|
|
321
321
|
def scan_tags
|
|
@@ -338,7 +338,7 @@ module NA
|
|
|
338
338
|
# @param regexes [Array] Regexes to check
|
|
339
339
|
# @param include_note [Boolean] Include note in search
|
|
340
340
|
# @return [Boolean]
|
|
341
|
-
def search_matches_none(regexes, include_note: true)
|
|
341
|
+
def search_matches_none?(regexes, include_note: true)
|
|
342
342
|
regexes.each do |rx|
|
|
343
343
|
regex = rx.is_a?(Regexp) ? rx : Regexp.new(rx, Regexp::IGNORECASE)
|
|
344
344
|
note_matches = include_note && @note.join(' ').match(regex)
|
|
@@ -352,7 +352,7 @@ module NA
|
|
|
352
352
|
# @param regexes [Array] Regexes to check
|
|
353
353
|
# @param include_note [Boolean] Include note in search
|
|
354
354
|
# @return [Boolean]
|
|
355
|
-
def search_matches_any(regexes, include_note: true)
|
|
355
|
+
def search_matches_any?(regexes, include_note: true)
|
|
356
356
|
return true if regexes.empty?
|
|
357
357
|
|
|
358
358
|
regexes.each do |rx|
|
|
@@ -368,7 +368,7 @@ module NA
|
|
|
368
368
|
# @param regexes [Array] Regexes to check
|
|
369
369
|
# @param include_note [Boolean] Include note in search
|
|
370
370
|
# @return [Boolean]
|
|
371
|
-
def search_matches_all(regexes, include_note: true)
|
|
371
|
+
def search_matches_all?(regexes, include_note: true)
|
|
372
372
|
regexes.each do |rx|
|
|
373
373
|
regex = rx.is_a?(Regexp) ? rx : Regexp.new(rx, Regexp::IGNORECASE)
|
|
374
374
|
note_matches = include_note && @note.join(' ').match(regex)
|
|
@@ -381,7 +381,7 @@ module NA
|
|
|
381
381
|
#
|
|
382
382
|
# @param tags [Array] Tags to check
|
|
383
383
|
# @return [Boolean]
|
|
384
|
-
def tag_matches_none(tags)
|
|
384
|
+
def tag_matches_none?(tags)
|
|
385
385
|
tags.each do |tag|
|
|
386
386
|
return false if compare_tag(tag)
|
|
387
387
|
end
|
|
@@ -392,7 +392,7 @@ module NA
|
|
|
392
392
|
#
|
|
393
393
|
# @param tags [Array] Tags to check
|
|
394
394
|
# @return [Boolean]
|
|
395
|
-
def tag_matches_any(tags)
|
|
395
|
+
def tag_matches_any?(tags)
|
|
396
396
|
return true if tags.empty?
|
|
397
397
|
|
|
398
398
|
tags.each do |tag|
|
|
@@ -405,7 +405,7 @@ module NA
|
|
|
405
405
|
#
|
|
406
406
|
# @param tags [Array] Tags to check
|
|
407
407
|
# @return [Boolean]
|
|
408
|
-
def tag_matches_all(tags)
|
|
408
|
+
def tag_matches_all?(tags)
|
|
409
409
|
tags.each do |tag|
|
|
410
410
|
return false unless compare_tag(tag)
|
|
411
411
|
end
|
data/lib/na/actions.rb
CHANGED
|
@@ -87,8 +87,8 @@ module NA
|
|
|
87
87
|
# Optimize template selection
|
|
88
88
|
template = if config[:no_files]
|
|
89
89
|
NA.theme[:templates][:no_file]
|
|
90
|
-
elsif config[:files]&.
|
|
91
|
-
config[:files].
|
|
90
|
+
elsif config[:files]&.any?
|
|
91
|
+
config[:files].one? ? NA.theme[:templates][:single_file] : NA.theme[:templates][:multi_file]
|
|
92
92
|
elsif depth > 1
|
|
93
93
|
NA.theme[:templates][:multi_file]
|
|
94
94
|
else
|
data/lib/na/next_action.rb
CHANGED
|
@@ -272,13 +272,13 @@ module NA
|
|
|
272
272
|
tag: tagged,
|
|
273
273
|
done: done })
|
|
274
274
|
|
|
275
|
-
unless todo.actions.
|
|
275
|
+
unless todo.actions.any?
|
|
276
276
|
NA.notify("#{NA.theme[:error]}No matching actions found in #{File.basename(target,
|
|
277
277
|
".#{NA.extension}").highlight_filename}")
|
|
278
278
|
return [todo.projects, NA::Actions.new]
|
|
279
279
|
end
|
|
280
280
|
|
|
281
|
-
return [todo.projects, todo.actions] if todo.actions.
|
|
281
|
+
return [todo.projects, todo.actions] if todo.actions.one? || all
|
|
282
282
|
|
|
283
283
|
# If target_line is specified, find the action at that specific line
|
|
284
284
|
if target_line
|
|
@@ -327,13 +327,15 @@ module NA
|
|
|
327
327
|
matches = nil
|
|
328
328
|
path.each_with_index do |part, i|
|
|
329
329
|
built.push(part)
|
|
330
|
-
|
|
331
|
-
|
|
330
|
+
built_path = built.join(':')
|
|
331
|
+
matches = todo.projects.select { |proj| proj.project =~ /^#{Regexp.escape(built_path)}/i }
|
|
332
|
+
exact_match = matches.find { |proj| proj.project.casecmp(built_path).zero? }
|
|
333
|
+
if exact_match
|
|
334
|
+
last_match = exact_match
|
|
335
|
+
else
|
|
332
336
|
final_match = last_match
|
|
333
337
|
new_path = path.slice(i, path.count - i)
|
|
334
338
|
break
|
|
335
|
-
else
|
|
336
|
-
last_match = matches.last
|
|
337
339
|
end
|
|
338
340
|
end
|
|
339
341
|
|
|
@@ -499,7 +501,24 @@ module NA
|
|
|
499
501
|
projects = find_projects(target)
|
|
500
502
|
# If move is set, update add.parent to the target project
|
|
501
503
|
add.parent = target_proj.project.split(':') if move && target_proj
|
|
502
|
-
|
|
504
|
+
project_path = add.parent.join(':')
|
|
505
|
+
target_proj ||= projects.select { |proj| proj.project =~ /^#{project_path}$/i }.first
|
|
506
|
+
|
|
507
|
+
if target_proj.nil? && !project_path.empty?
|
|
508
|
+
display_path = project_path.tr(':', '/')
|
|
509
|
+
prompt = NA::Color.template(
|
|
510
|
+
"#{NA.theme[:warning]}Project #{NA.theme[:file]}#{display_path}#{NA.theme[:warning]} doesn't exist, create it?"
|
|
511
|
+
)
|
|
512
|
+
should_create = NA.yn(prompt, default: true)
|
|
513
|
+
NA.notify("#{NA.theme[:error]}Cancelled", exit_code: 1) unless should_create
|
|
514
|
+
|
|
515
|
+
created_proj = insert_project(target, project_path)
|
|
516
|
+
contents = target.read_file.split("\n")
|
|
517
|
+
projects = find_projects(target)
|
|
518
|
+
target_proj = projects.select { |proj| proj.project =~ /^#{project_path}$/i }.first || created_proj
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
add.parent = target_proj.project.split(':') if target_proj
|
|
503
522
|
indent = target_proj ? ("\t" * target_proj.indent) : ''
|
|
504
523
|
|
|
505
524
|
# Format note for insertion
|
|
@@ -681,6 +700,7 @@ module NA
|
|
|
681
700
|
# @return [void]
|
|
682
701
|
def add_action(file, project, action, note = [], priority: 0, finish: false, append: false, started_at: nil, done_at: nil, duration_seconds: nil)
|
|
683
702
|
parent = project.split(%r{[:/]})
|
|
703
|
+
file_project = File.basename(file, ".#{NA.extension}")
|
|
684
704
|
|
|
685
705
|
if NA.global_file
|
|
686
706
|
if NA.cwd_is == :tag
|
|
@@ -690,7 +710,7 @@ module NA
|
|
|
690
710
|
end
|
|
691
711
|
end
|
|
692
712
|
|
|
693
|
-
action = Action.new(file,
|
|
713
|
+
action = Action.new(file, file_project, parent, action, nil, note)
|
|
694
714
|
|
|
695
715
|
update_action(file, nil,
|
|
696
716
|
add: action,
|
|
@@ -869,7 +889,7 @@ module NA
|
|
|
869
889
|
required = search.filter { |s| s[:required] && !s[:negate] }.map { |t| t[:token] }
|
|
870
890
|
negated = search.filter { |s| s[:negate] }.map { |t| t[:token] }
|
|
871
891
|
|
|
872
|
-
optional.push('*') if optional.
|
|
892
|
+
optional.push('*') if optional.none? && required.none? && negated.any?
|
|
873
893
|
if optional == negated
|
|
874
894
|
required = ['*']
|
|
875
895
|
optional = ['*']
|
|
@@ -886,7 +906,7 @@ module NA
|
|
|
886
906
|
else
|
|
887
907
|
dirs.delete_if do |d|
|
|
888
908
|
!d.sub(/\.#{NA.extension}$/, '')
|
|
889
|
-
.dir_matches(any: optional, all: required, none: negated, distance: 2, require_last: false)
|
|
909
|
+
.dir_matches?(any: optional, all: required, none: negated, distance: 2, require_last: false)
|
|
890
910
|
end
|
|
891
911
|
end
|
|
892
912
|
|
|
@@ -1225,7 +1245,7 @@ module NA
|
|
|
1225
1245
|
file = database_path(file: 'saved_searches.yml')
|
|
1226
1246
|
searches = load_searches
|
|
1227
1247
|
|
|
1228
|
-
NA.notify("#{NA.theme[:error]}No search definitions found", exit_code: 1) unless searches.
|
|
1248
|
+
NA.notify("#{NA.theme[:error]}No search definitions found", exit_code: 1) unless searches.any?
|
|
1229
1249
|
|
|
1230
1250
|
editor = NA.default_editor
|
|
1231
1251
|
NA.notify("#{NA.theme[:error]}No $EDITOR defined", exit_code: 1) unless editor && TTY::Which.exist?(editor)
|
|
@@ -1283,7 +1303,7 @@ module NA
|
|
|
1283
1303
|
default_args = [%(--prompt="#{prompt}"), "--height=#{options.count + 2}", '--info=inline']
|
|
1284
1304
|
default_args << '--multi' if multiple
|
|
1285
1305
|
default_args << '--bind ctrl-a:select-all' if multiple
|
|
1286
|
-
header = "esc: cancel,#{
|
|
1306
|
+
header = "esc: cancel,#{' tab: multi-select, ctrl-a: select all,' if multiple} return: confirm"
|
|
1287
1307
|
default_args << %(--header="#{header}")
|
|
1288
1308
|
default_args.concat(fzf_args)
|
|
1289
1309
|
options = NA::Color.uncolor(NA::Color.template(options.join("\n")))
|
|
@@ -1310,11 +1330,11 @@ module NA
|
|
|
1310
1330
|
mult_res = []
|
|
1311
1331
|
result = result.gsub(',', ' ').gsub(/ +/, ' ').split(/ /)
|
|
1312
1332
|
result.each do |r|
|
|
1313
|
-
mult_res << options[r.to_i - 1] if r.to_i
|
|
1333
|
+
mult_res << options[r.to_i - 1] if r.to_i.positive?
|
|
1314
1334
|
end
|
|
1315
1335
|
mult_res.join("\n")
|
|
1316
1336
|
else
|
|
1317
|
-
result.to_i
|
|
1337
|
+
result.to_i.positive? ? options[result.to_i - 1] : nil
|
|
1318
1338
|
end
|
|
1319
1339
|
end
|
|
1320
1340
|
|
data/lib/na/string.rb
CHANGED
|
@@ -95,7 +95,7 @@ class ::String
|
|
|
95
95
|
# Returns the project name if matched, otherwise nil.
|
|
96
96
|
# @return [String, nil]
|
|
97
97
|
def project
|
|
98
|
-
m = match(/^([ \t]*)([
|
|
98
|
+
m = match(/^([ \t]*)([^-][^@:]*?): *(@\S+ *)*$/)
|
|
99
99
|
m ? m[2] : nil
|
|
100
100
|
end
|
|
101
101
|
|
|
@@ -228,7 +228,7 @@ class ::String
|
|
|
228
228
|
def dir_to_rx(distance: 1, require_last: true)
|
|
229
229
|
"#{split(%r{[/:]}).map do |comp|
|
|
230
230
|
comp.chars.join(".{0,#{distance}}").gsub('*', '[^ ]*?')
|
|
231
|
-
end.join('.*?/.*?')}#{
|
|
231
|
+
end.join('.*?/.*?')}#{'[^/]*?$' if require_last}"
|
|
232
232
|
end
|
|
233
233
|
|
|
234
234
|
# Check if the string matches directory patterns using any, all, and none criteria.
|
|
@@ -238,11 +238,11 @@ class ::String
|
|
|
238
238
|
# @param require_last [Boolean] Require last segment match
|
|
239
239
|
# @param distance [Integer] Allowed character distance in regex
|
|
240
240
|
# @return [Boolean] True if matches criteria
|
|
241
|
-
def dir_matches(any: [], all: [], none: [], require_last: true, distance: 1)
|
|
241
|
+
def dir_matches?(any: [], all: [], none: [], require_last: true, distance: 1)
|
|
242
242
|
any_rx = any.map { |q| q.dir_to_rx(distance: distance, require_last: require_last) }
|
|
243
243
|
all_rx = all.map { |q| q.dir_to_rx(distance: distance, require_last: require_last) }
|
|
244
244
|
none_rx = none.map { |q| q.dir_to_rx(distance: distance, require_last: false) }
|
|
245
|
-
matches_any(any_rx) && matches_all(all_rx) && matches_none(none_rx)
|
|
245
|
+
matches_any?(any_rx) && matches_all?(all_rx) && matches_none?(none_rx)
|
|
246
246
|
end
|
|
247
247
|
|
|
248
248
|
# Check if the string matches any, all, and none regex patterns.
|
|
@@ -250,8 +250,8 @@ class ::String
|
|
|
250
250
|
# @param all [Array] Patterns where all must match
|
|
251
251
|
# @param none [Array] Patterns where none must match
|
|
252
252
|
# @return [Boolean] True if matches criteria
|
|
253
|
-
def matches(any: [], all: [], none: [])
|
|
254
|
-
matches_any(any) && matches_all(all) && matches_none(none)
|
|
253
|
+
def matches?(any: [], all: [], none: [])
|
|
254
|
+
matches_any?(any) && matches_all?(all) && matches_none?(none)
|
|
255
255
|
end
|
|
256
256
|
|
|
257
257
|
# Convert wildcard characters to regular expressions
|
|
@@ -374,7 +374,7 @@ class ::String
|
|
|
374
374
|
# Returns true if none of the regexes match the string.
|
|
375
375
|
# @param regexes [Array] Array of regex patterns
|
|
376
376
|
# @return [Boolean] True if none match
|
|
377
|
-
def matches_none(regexes)
|
|
377
|
+
def matches_none?(regexes)
|
|
378
378
|
regexes.each do |rx|
|
|
379
379
|
return false if match(Regexp.new(rx, Regexp::IGNORECASE))
|
|
380
380
|
end
|
|
@@ -384,7 +384,7 @@ class ::String
|
|
|
384
384
|
# Returns true if any of the regexes match the string.
|
|
385
385
|
# @param regexes [Array] Array of regex patterns
|
|
386
386
|
# @return [Boolean] True if any match
|
|
387
|
-
def matches_any(regexes)
|
|
387
|
+
def matches_any?(regexes)
|
|
388
388
|
regexes.each do |rx|
|
|
389
389
|
return true if match(Regexp.new(rx, Regexp::IGNORECASE))
|
|
390
390
|
end
|
|
@@ -394,7 +394,7 @@ class ::String
|
|
|
394
394
|
# Returns true if all of the regexes match the string.
|
|
395
395
|
# @param regexes [Array] Array of regex patterns
|
|
396
396
|
# @return [Boolean] True if all match
|
|
397
|
-
def matches_all(regexes)
|
|
397
|
+
def matches_all?(regexes)
|
|
398
398
|
regexes.each do |rx|
|
|
399
399
|
return false unless match(Regexp.new(rx, Regexp::IGNORECASE))
|
|
400
400
|
end
|
data/lib/na/todo.rb
CHANGED
|
@@ -180,7 +180,7 @@ module NA
|
|
|
180
180
|
action = line.action
|
|
181
181
|
new_action = NA::Action.new(file, File.basename(file, ".#{NA.extension}"), parent.dup, action, idx)
|
|
182
182
|
|
|
183
|
-
projects[-1].last_line = idx if projects.
|
|
183
|
+
projects[-1].last_line = idx if projects.any?
|
|
184
184
|
|
|
185
185
|
# Tag matching
|
|
186
186
|
has_tag = !optional_tag.empty? || !required_tag.empty? || !negated_tag.empty?
|
|
@@ -191,8 +191,8 @@ module NA
|
|
|
191
191
|
actions.push(new_action)
|
|
192
192
|
in_action = true
|
|
193
193
|
elsif in_action
|
|
194
|
-
actions[-1].note.push(line.strip) if actions.
|
|
195
|
-
projects[-1].last_line = idx if projects.
|
|
194
|
+
actions[-1].note.push(line.strip) if actions.any?
|
|
195
|
+
projects[-1].last_line = idx if projects.any?
|
|
196
196
|
end
|
|
197
197
|
end
|
|
198
198
|
projects = projects.dup
|
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.2.
|
|
12
|
+
The current version of `na` is <!--VER-->1.2.91<!--END VER-->.
|
|
13
13
|
|
|
14
14
|
<!--GITHUB-->
|
|
15
15
|
### Table of contents
|