na 1.2.74 → 1.2.76
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/.rubocop.yml +4 -0
- data/.rubocop_todo.yml +623 -0
- data/.travis.yml +1 -1
- data/CHANGELOG.md +25 -8
- data/Gemfile +1 -0
- data/Gemfile.lock +55 -39
- data/README.md +5 -3
- data/Rakefile +147 -32
- data/bin/commands/find.rb +71 -67
- data/bin/commands/next.rb +85 -85
- data/bin/commands/tagged.rb +64 -60
- data/bin/na +58 -1
- data/docker/Dockerfile +10 -0
- data/docker/Dockerfile-2.6 +11 -0
- data/docker/Dockerfile-2.7 +11 -0
- data/docker/Dockerfile-3.0 +11 -0
- data/docker/Dockerfile-3.3 +12 -0
- data/docker/bash_profile +17 -0
- data/docker/inputrc +57 -0
- data/docker/sources.list +11 -0
- data/lib/na/actions.rb +48 -46
- data/lib/na/next_action.rb +1 -1
- data/lib/na/version.rb +1 -1
- data/na.gemspec +2 -3
- data/scripts/generate-fish-completions.rb +170 -0
- data/scripts/runtests.sh +5 -0
- data/src/_README.md +1 -1
- metadata +49 -51
data/Gemfile.lock
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
na (1.2.
|
4
|
+
na (1.2.76)
|
5
5
|
chronic (~> 0.10, >= 0.10.2)
|
6
|
+
git (~> 3.0.0)
|
6
7
|
gli (~> 2.21.0)
|
7
8
|
mdless (~> 1.0, >= 1.0.32)
|
8
9
|
tty-reader (~> 0.9, >= 0.9.0)
|
@@ -12,63 +13,78 @@ PATH
|
|
12
13
|
GEM
|
13
14
|
remote: https://rubygems.org/
|
14
15
|
specs:
|
15
|
-
|
16
|
+
activesupport (8.0.2)
|
17
|
+
base64
|
18
|
+
benchmark (>= 0.3)
|
19
|
+
bigdecimal
|
20
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
21
|
+
connection_pool (>= 2.2.5)
|
22
|
+
drb
|
23
|
+
i18n (>= 1.6, < 2)
|
24
|
+
logger (>= 1.4.2)
|
25
|
+
minitest (>= 5.1)
|
26
|
+
securerandom (>= 0.3)
|
27
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
28
|
+
uri (>= 0.13.1)
|
29
|
+
addressable (2.8.7)
|
30
|
+
public_suffix (>= 2.0.2, < 7.0)
|
31
|
+
base64 (0.2.0)
|
32
|
+
benchmark (0.4.0)
|
33
|
+
bigdecimal (3.1.9)
|
16
34
|
chronic (0.10.2)
|
35
|
+
concurrent-ruby (1.3.5)
|
36
|
+
connection_pool (2.5.1)
|
37
|
+
drb (2.2.1)
|
38
|
+
git (3.0.0)
|
39
|
+
activesupport (>= 5.0)
|
40
|
+
addressable (~> 2.8)
|
41
|
+
process_executer (~> 1.3)
|
42
|
+
rchardet (~> 1.9)
|
17
43
|
gli (2.21.5)
|
18
|
-
|
19
|
-
|
20
|
-
|
44
|
+
i18n (1.14.7)
|
45
|
+
concurrent-ruby (~> 1.0)
|
46
|
+
logger (1.6.6)
|
21
47
|
mdless (1.0.37)
|
22
|
-
minitest (5.
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
racc (1.8.1)
|
28
|
-
rainbow (3.1.1)
|
29
|
-
rake (0.9.6)
|
48
|
+
minitest (5.25.5)
|
49
|
+
process_executer (1.3.0)
|
50
|
+
public_suffix (6.0.1)
|
51
|
+
rake (13.2.1)
|
52
|
+
rchardet (1.9.0)
|
30
53
|
rdoc (4.3.0)
|
31
|
-
|
32
|
-
rubocop (1.74.0)
|
33
|
-
json (~> 2.3)
|
34
|
-
language_server-protocol (~> 3.17.0.2)
|
35
|
-
lint_roller (~> 1.1.0)
|
36
|
-
parallel (~> 1.10)
|
37
|
-
parser (>= 3.3.0.2)
|
38
|
-
rainbow (>= 2.2.2, < 4.0)
|
39
|
-
regexp_parser (>= 2.9.3, < 3.0)
|
40
|
-
rubocop-ast (>= 1.38.0, < 2.0)
|
41
|
-
ruby-progressbar (~> 1.7)
|
42
|
-
unicode-display_width (>= 2.4.0, < 4.0)
|
43
|
-
rubocop-ast (1.38.1)
|
44
|
-
parser (>= 3.3.1.0)
|
45
|
-
ruby-progressbar (1.13.0)
|
54
|
+
securerandom (0.4.1)
|
46
55
|
tty-cursor (0.7.1)
|
47
56
|
tty-reader (0.9.0)
|
48
57
|
tty-cursor (~> 0.7)
|
49
58
|
tty-screen (~> 0.8)
|
50
59
|
wisper (~> 2.0)
|
51
60
|
tty-screen (0.8.2)
|
61
|
+
tty-spinner (0.9.3)
|
62
|
+
tty-cursor (~> 0.7)
|
52
63
|
tty-which (0.5.0)
|
53
|
-
|
54
|
-
|
55
|
-
|
64
|
+
tzinfo (2.0.6)
|
65
|
+
concurrent-ruby (~> 1.0)
|
66
|
+
uri (1.0.3)
|
56
67
|
wisper (2.0.1)
|
57
|
-
yard (0.9.34)
|
58
68
|
|
59
69
|
PLATFORMS
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
70
|
+
aarch64-linux-gnu
|
71
|
+
aarch64-linux-musl
|
72
|
+
arm-linux-gnu
|
73
|
+
arm-linux-musl
|
74
|
+
arm64-darwin
|
75
|
+
ruby
|
76
|
+
x86-linux-gnu
|
77
|
+
x86-linux-musl
|
78
|
+
x86_64-darwin
|
79
|
+
x86_64-linux-gnu
|
80
|
+
x86_64-linux-musl
|
64
81
|
|
65
82
|
DEPENDENCIES
|
66
83
|
minitest (~> 5.14)
|
67
84
|
na!
|
68
|
-
rake
|
85
|
+
rake
|
69
86
|
rdoc (~> 4.3)
|
70
|
-
|
71
|
-
yard (~> 0.9, >= 0.9.26)
|
87
|
+
tty-spinner (~> 0.9, >= 0.9.0)
|
72
88
|
|
73
89
|
BUNDLED WITH
|
74
90
|
2.6.6
|
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.76.
|
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.
|
79
|
+
1.2.76
|
80
80
|
|
81
81
|
GLOBAL OPTIONS
|
82
82
|
-a, --add - Add a next action (deprecated, for backwards compatibility)
|
@@ -93,8 +93,9 @@ GLOBAL OPTIONS
|
|
93
93
|
-p, --priority=PRIORITY - Set a priority 0-5 (deprecated, for backwards compatibility) (default: none)
|
94
94
|
--[no-]pager - Enable pagination (default: enabled)
|
95
95
|
-r, --[no-]recurse - Recurse 3 directories deep (deprecated, for backwards compatability)
|
96
|
+
--[no-]repo - Use a taskpaper file named after the git repository (default: enabled)
|
96
97
|
-t, --na_tag=TAG - Tag to consider a next action (default: na)
|
97
|
-
--template=
|
98
|
+
--template=arg - Provide a template for new/blank todo files, use initconfig to make permanent (default: none)
|
98
99
|
--version - Display the program version
|
99
100
|
|
100
101
|
COMMANDS
|
@@ -223,6 +224,7 @@ COMMAND OPTIONS
|
|
223
224
|
-e, --regex - Interpret search pattern as regular expression
|
224
225
|
--in=TODO_PATH - Show actions from a specific todo file in history. May use wildcards (* and ?) (default: none)
|
225
226
|
--nest - Output actions nested by file
|
227
|
+
--no_file - No filename in output
|
226
228
|
--[no-]notes - Include notes in output
|
227
229
|
-o, --or - Combine search tokens with OR, displaying actions matching ANY of the terms
|
228
230
|
--omnifocus - Output actions nested by file and project
|
data/Rakefile
CHANGED
@@ -1,43 +1,70 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
require "rake/clean"
|
2
|
+
require "rubygems"
|
3
|
+
require "rubygems/package_task"
|
4
|
+
require "rdoc/task"
|
5
|
+
require "bump/tasks"
|
6
|
+
require "bundler/gem_tasks"
|
7
|
+
require "rspec/core/rake_task"
|
8
|
+
require "rubocop/rake_task"
|
9
|
+
require "yard"
|
10
|
+
require "tty-spinner"
|
11
|
+
require "English"
|
6
12
|
|
7
13
|
YARD::Rake::YardocTask.new do |t|
|
8
|
-
|
9
|
-
|
10
|
-
|
14
|
+
t.files = ["lib/na/*.rb"]
|
15
|
+
t.options = ["--markup-provider=redcarpet", "--markup=markdown", "--no-private", "-p", "yard_templates"]
|
16
|
+
t.stats_options = ["--list-undoc"] # Uncommented this line for stats options
|
17
|
+
end
|
18
|
+
|
19
|
+
## Docker error class
|
20
|
+
class DockerError < StandardError
|
21
|
+
def initialize(msg = nil)
|
22
|
+
msg = msg ? "Docker error: #{msg}" : "Docker error"
|
23
|
+
super(msg)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
task default: %i[test yard]
|
28
|
+
|
29
|
+
desc "Run test suite"
|
30
|
+
task test: %i[rubocop spec]
|
31
|
+
|
32
|
+
RSpec::Core::RakeTask.new do |t|
|
33
|
+
t.rspec_opts = "--format documentation"
|
34
|
+
end
|
35
|
+
|
36
|
+
RuboCop::RakeTask.new do |t|
|
37
|
+
t.formatters = ["progress"]
|
11
38
|
end
|
12
39
|
|
13
40
|
task :doc, [*Rake.application[:yard].arg_names] => [:yard]
|
14
41
|
|
15
42
|
Rake::RDocTask.new do |rd|
|
16
43
|
rd.main = "README.rdoc"
|
17
|
-
rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
|
18
|
-
rd.title =
|
44
|
+
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb", "bin/**/*")
|
45
|
+
rd.title = "na"
|
19
46
|
end
|
20
47
|
|
21
|
-
spec = eval(File.read(
|
48
|
+
spec = eval(File.read("na.gemspec"))
|
22
49
|
|
23
50
|
Gem::PackageTask.new(spec) do |pkg|
|
24
51
|
end
|
25
|
-
require
|
52
|
+
require "rake/testtask"
|
26
53
|
Rake::TestTask.new do |t|
|
27
54
|
t.libs << "test"
|
28
|
-
t.test_files = FileList[
|
55
|
+
t.test_files = FileList["test/*_test.rb"]
|
29
56
|
end
|
30
57
|
|
31
|
-
desc
|
58
|
+
desc "Install current gem in all versions of asdf-controlled ruby"
|
32
59
|
task :install do
|
33
|
-
Rake::Task[
|
34
|
-
Rake::Task[
|
35
|
-
Dir.chdir
|
36
|
-
file = Dir.glob(
|
60
|
+
Rake::Task["clobber"].invoke
|
61
|
+
Rake::Task["package"].invoke
|
62
|
+
Dir.chdir "pkg"
|
63
|
+
file = Dir.glob("*.gem").last
|
37
64
|
|
38
65
|
current_ruby = `asdf current ruby`.match(/(\d.\d+.\d+)/)[1]
|
39
66
|
|
40
|
-
`asdf list ruby`.split.map { |ruby| ruby.strip.sub(/^*/,
|
67
|
+
`asdf list ruby`.split.map { |ruby| ruby.strip.sub(/^*/, "") }.each do |ruby|
|
41
68
|
`asdf shell ruby #{ruby}`
|
42
69
|
puts `gem install #{file}`
|
43
70
|
end
|
@@ -45,10 +72,10 @@ task :install do
|
|
45
72
|
`asdf shell ruby #{current_ruby}`
|
46
73
|
end
|
47
74
|
|
48
|
-
desc
|
75
|
+
desc "Development version check"
|
49
76
|
task :ver do
|
50
77
|
gver = `git ver`
|
51
|
-
cver = IO.read(File.join(File.dirname(__FILE__),
|
78
|
+
cver = IO.read(File.join(File.dirname(__FILE__), "CHANGELOG.md")).match(/^#+ (\d+\.\d+\.\d+(\w+)?)/)[1]
|
52
79
|
res = `grep VERSION lib/na/version.rb`
|
53
80
|
version = res.match(/VERSION *= *['"](\d+\.\d+\.\d+(\w+)?)/)[1]
|
54
81
|
puts "git tag: #{gver}"
|
@@ -56,22 +83,22 @@ task :ver do
|
|
56
83
|
puts "changelog: #{cver}"
|
57
84
|
end
|
58
85
|
|
59
|
-
desc
|
86
|
+
desc "Changelog version check"
|
60
87
|
task :cver do
|
61
|
-
puts IO.read(File.join(File.dirname(__FILE__),
|
88
|
+
puts IO.read(File.join(File.dirname(__FILE__), "CHANGELOG.md")).match(/^#+ (\d+\.\d+\.\d+(\w+)?)/)[1]
|
62
89
|
end
|
63
90
|
|
64
|
-
desc
|
91
|
+
desc "Bump incremental version number"
|
65
92
|
task :bump, :type do |_, args|
|
66
|
-
args.with_defaults(type:
|
67
|
-
version_file =
|
93
|
+
args.with_defaults(type: "inc")
|
94
|
+
version_file = "lib/na/version.rb"
|
68
95
|
content = IO.read(version_file)
|
69
96
|
content.sub!(/VERSION = '(?<major>\d+)\.(?<minor>\d+)\.(?<inc>\d+)(?<pre>\S+)?'/) do
|
70
97
|
m = Regexp.last_match
|
71
|
-
major = m[
|
72
|
-
minor = m[
|
73
|
-
inc = m[
|
74
|
-
pre = m[
|
98
|
+
major = m["major"].to_i
|
99
|
+
minor = m["minor"].to_i
|
100
|
+
inc = m["inc"].to_i
|
101
|
+
pre = m["pre"]
|
75
102
|
|
76
103
|
case args[:type]
|
77
104
|
when /^maj/
|
@@ -88,7 +115,95 @@ task :bump, :type do |_, args|
|
|
88
115
|
$stdout.puts "At version #{major}.#{minor}.#{inc}#{pre}"
|
89
116
|
"VERSION = '#{major}.#{minor}.#{inc}#{pre}'"
|
90
117
|
end
|
91
|
-
File.open(version_file,
|
118
|
+
File.open(version_file, "w+") { |f| f.puts content }
|
119
|
+
end
|
120
|
+
|
121
|
+
# task default: %i[test clobber package]
|
122
|
+
|
123
|
+
desc "Remove packages"
|
124
|
+
task :clobber_packages do
|
125
|
+
FileUtils.rm_f "pkg/*"
|
126
|
+
end
|
127
|
+
# Make a prerequisite of the preexisting clobber task
|
128
|
+
desc "Clobber files"
|
129
|
+
task clobber: :clobber_packages
|
130
|
+
|
131
|
+
desc "Get Script Version"
|
132
|
+
task :sver do
|
133
|
+
res = `grep VERSION lib/na/version.rb`
|
134
|
+
version = res.match(/VERSION *= *['"](\d+\.\d+\.\d+(\w+)?)/)[1]
|
135
|
+
print version
|
136
|
+
end
|
137
|
+
|
138
|
+
desc "Run tests in Docker"
|
139
|
+
task :dockertest, :version, :login, :attempt do |_, args|
|
140
|
+
args.with_defaults(version: "all", login: false, attempt: 1)
|
141
|
+
`open -a Docker`
|
142
|
+
|
143
|
+
Rake::Task["clobber"].reenable
|
144
|
+
Rake::Task["clobber"].invoke
|
145
|
+
Rake::Task["build"].reenable
|
146
|
+
Rake::Task["build"].invoke
|
147
|
+
|
148
|
+
case args[:version]
|
149
|
+
when /^a/
|
150
|
+
%w[6 7 3].each do |v|
|
151
|
+
Rake::Task["dockertest"].reenable
|
152
|
+
Rake::Task["dockertest"].invoke(v, false)
|
153
|
+
end
|
154
|
+
Process.exit 0
|
155
|
+
when /^3\.?3/
|
156
|
+
img = "natest33"
|
157
|
+
file = "docker/Dockerfile-3.3"
|
158
|
+
when /^3/
|
159
|
+
version = "3.0"
|
160
|
+
img = "natest3"
|
161
|
+
file = "docker/Dockerfile-3.0"
|
162
|
+
when /6$/
|
163
|
+
version = "2.6"
|
164
|
+
img = "natest26"
|
165
|
+
file = "docker/Dockerfile-2.6"
|
166
|
+
when /(^2|7$)/
|
167
|
+
version = "2.7"
|
168
|
+
img = "natest27"
|
169
|
+
file = "docker/Dockerfile-2.7"
|
170
|
+
else
|
171
|
+
version = "3.0.1"
|
172
|
+
img = "natest"
|
173
|
+
file = "docker/Dockerfile"
|
174
|
+
end
|
175
|
+
|
176
|
+
puts `docker build . --file #{file} -t #{img}`
|
177
|
+
|
178
|
+
raise DockerError, "Error building docker image" unless $CHILD_STATUS.success?
|
179
|
+
|
180
|
+
dirs = {
|
181
|
+
File.dirname(__FILE__) => "/na",
|
182
|
+
File.expand_path("~/.config") => "/root/.config"
|
183
|
+
}
|
184
|
+
dir_args = dirs.map { |s, d| " -v '#{s}:#{d}'" }.join(" ")
|
185
|
+
exec "docker run #{dir_args} -it #{img} /bin/bash -l" if args[:login]
|
186
|
+
|
187
|
+
spinner = TTY::Spinner.new("[:spinner] Running tests (#{version})...", hide_cursor: true)
|
188
|
+
|
189
|
+
spinner.auto_spin
|
190
|
+
`docker run --rm #{dir_args} -it #{img}`
|
191
|
+
# raise DockerError.new("Error running docker image") unless $CHILD_STATUS.success?
|
192
|
+
|
193
|
+
# commit = puts `bash -c "docker commit $(docker ps -a|grep #{img}|awk '{print $1}'|head -n 1) #{img}"`.strip
|
194
|
+
$CHILD_STATUS.success? ? spinner.success : spinner.error
|
195
|
+
spinner.stop
|
196
|
+
|
197
|
+
# puts res
|
198
|
+
# puts commit&.empty? ? "Error commiting Docker tag #{img}" : "Committed Docker tag #{img}"
|
199
|
+
rescue DockerError
|
200
|
+
raise StandardError.new("Docker not responding") if args[:attempt] > 3
|
201
|
+
|
202
|
+
`open -a Docker`
|
203
|
+
sleep 3
|
204
|
+
Rake::Task["dockertest"].reenable
|
205
|
+
Rake::Task["dockertest"].invoke(args[:version], args[:login], args[:attempt] + 1)
|
92
206
|
end
|
93
207
|
|
94
|
-
|
208
|
+
desc "alias for build"
|
209
|
+
task package: :build
|
data/bin/commands/find.rb
CHANGED
@@ -2,111 +2,114 @@
|
|
2
2
|
|
3
3
|
class App
|
4
4
|
extend GLI::App
|
5
|
-
desc
|
6
|
-
long_desc
|
5
|
+
desc "Find actions matching a search pattern"
|
6
|
+
long_desc "Search tokens are separated by spaces. Actions matching all tokens in the pattern will be shown
|
7
7
|
(partial matches allowed). Add a + before a token to make it required, e.g. `na find +feature +maybe`,
|
8
|
-
add a - or ! to ignore matches containing that token.
|
9
|
-
arg_name
|
8
|
+
add a - or ! to ignore matches containing that token."
|
9
|
+
arg_name "PATTERN"
|
10
10
|
command %i[find grep search] do |c|
|
11
|
-
c.example
|
12
|
-
c.example
|
13
|
-
c.example
|
11
|
+
c.example "na find feature idea swift", desc: "Find all actions containing feature, idea, and swift"
|
12
|
+
c.example "na find feature idea -swift", desc: "Find all actions containing feature and idea but NOT swift"
|
13
|
+
c.example "na find -x feature idea", desc: 'Find all actions containing the exact text "feature idea"'
|
14
14
|
|
15
|
-
c.desc
|
15
|
+
c.desc "Interpret search pattern as regular expression"
|
16
16
|
c.switch %i[e regex], negatable: false
|
17
17
|
|
18
|
-
c.desc
|
18
|
+
c.desc "Match pattern exactly"
|
19
19
|
c.switch %i[x exact], negatable: false
|
20
20
|
|
21
|
-
c.desc
|
22
|
-
c.arg_name
|
21
|
+
c.desc "Recurse to depth"
|
22
|
+
c.arg_name "DEPTH"
|
23
23
|
c.flag %i[d depth], type: :integer, must_match: /^\d+$/
|
24
24
|
|
25
|
-
c.desc
|
26
|
-
c.arg_name
|
25
|
+
c.desc "Show actions from a specific todo file in history. May use wildcards (* and ?)"
|
26
|
+
c.arg_name "TODO_PATH"
|
27
27
|
c.flag %i[in]
|
28
28
|
|
29
|
-
c.desc
|
29
|
+
c.desc "Include notes in output"
|
30
30
|
c.switch %i[notes], negatable: true, default_value: false
|
31
31
|
|
32
|
-
c.desc
|
32
|
+
c.desc "Include notes in search"
|
33
33
|
c.switch %i[search_notes], negatable: true, default_value: true
|
34
34
|
|
35
|
-
c.desc
|
35
|
+
c.desc "Combine search tokens with OR, displaying actions matching ANY of the terms"
|
36
36
|
c.switch %i[o or], negatable: false
|
37
37
|
|
38
|
-
c.desc
|
39
|
-
c.arg_name
|
38
|
+
c.desc "Show actions from a specific project"
|
39
|
+
c.arg_name "PROJECT[/SUBPROJECT]"
|
40
40
|
c.flag %i[proj project]
|
41
41
|
|
42
|
-
c.desc
|
43
|
-
c.arg_name
|
42
|
+
c.desc "Match actions containing tag. Allows value comparisons"
|
43
|
+
c.arg_name "TAG"
|
44
44
|
c.flag %i[tagged], multiple: true
|
45
45
|
|
46
|
-
c.desc
|
46
|
+
c.desc "Include @done actions"
|
47
47
|
c.switch %i[done]
|
48
48
|
|
49
|
-
c.desc
|
49
|
+
c.desc "Show actions not matching search pattern"
|
50
50
|
c.switch %i[v invert], negatable: false
|
51
51
|
|
52
|
-
c.desc
|
53
|
-
c.arg_name
|
52
|
+
c.desc "Save this search for future use"
|
53
|
+
c.arg_name "TITLE"
|
54
54
|
c.flag %i[save]
|
55
55
|
|
56
|
-
c.desc
|
56
|
+
c.desc "Output actions nested by file"
|
57
57
|
c.switch %[nest], negatable: false
|
58
58
|
|
59
|
-
c.desc
|
59
|
+
c.desc "No filename in output"
|
60
|
+
c.switch %i[no_file], negatable: false
|
61
|
+
|
62
|
+
c.desc "Output actions nested by file and project"
|
60
63
|
c.switch %[omnifocus], negatable: false
|
61
64
|
|
62
65
|
c.action do |global_options, options, args|
|
63
66
|
options[:nest] = true if options[:omnifocus]
|
64
67
|
|
65
68
|
if options[:save]
|
66
|
-
title = options[:save].gsub(/[^a-z0-9]/,
|
67
|
-
cmd = NA.command_line.join(
|
69
|
+
title = options[:save].gsub(/[^a-z0-9]/, "_").gsub(/_+/, "_")
|
70
|
+
cmd = NA.command_line.join(" ").sub(/ --save[= ]*\S+/, "").split(" ").map { |t| %("#{t}") }.join(" ")
|
68
71
|
NA.save_search(title, cmd)
|
69
72
|
end
|
70
73
|
|
71
74
|
depth = if global_options[:recurse] && options[:depth].nil? && global_options[:depth] == 1
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
75
|
+
3
|
76
|
+
else
|
77
|
+
options[:depth].nil? ? global_options[:depth].to_i : options[:depth].to_i
|
78
|
+
end
|
76
79
|
|
77
80
|
if options[:exact] || options[:regex]
|
78
|
-
search = args.join(
|
81
|
+
search = args.join(" ")
|
79
82
|
else
|
80
83
|
rx = [
|
81
84
|
'(?<=\A|[ ,])(?<req>[+!-])?@(?<tag>[^ *=<>$*\^,@(]+)',
|
82
85
|
'(?:\((?<value>.*?)\)| *(?<op>[=<>~]{1,2}|[*$\^]=) *',
|
83
|
-
'(?<val>.*?(?=\Z|[,@])))?'
|
84
|
-
].join(
|
85
|
-
search = args.join(
|
86
|
+
'(?<val>.*?(?=\Z|[,@])))?',
|
87
|
+
].join("")
|
88
|
+
search = args.join(" ").gsub(Regexp.new(rx)) do
|
86
89
|
m = Regexp.last_match
|
87
|
-
string = if m[
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
options[:tagged] << string.sub(/@/,
|
93
|
-
|
90
|
+
string = if m["value"]
|
91
|
+
"#{m["req"]}#{m["tag"]}=#{m["value"]}"
|
92
|
+
else
|
93
|
+
m[0]
|
94
|
+
end
|
95
|
+
options[:tagged] << string.sub(/@/, "")
|
96
|
+
""
|
94
97
|
end
|
95
98
|
end
|
96
99
|
|
97
|
-
search = search.gsub(/ +/,
|
100
|
+
search = search.gsub(/ +/, " ").strip
|
98
101
|
|
99
|
-
all_req = options[:tagged].join(
|
102
|
+
all_req = options[:tagged].join(" ") !~ /(?<=[, ])[+!-]/ && !options[:or]
|
100
103
|
tags = []
|
101
|
-
options[:tagged].join(
|
104
|
+
options[:tagged].join(",").split(/ *, */).each do |arg|
|
102
105
|
m = arg.match(/^(?<req>[+!-])?(?<tag>[^ =<>$~\^]+?) *(?:(?<op>[=<>~]{1,2}|[*$\^]=) *(?<val>.*?))?$/)
|
103
106
|
|
104
107
|
tags.push({
|
105
|
-
tag: m[
|
106
|
-
comp: m[
|
107
|
-
value: m[
|
108
|
-
required: all_req || (!m[
|
109
|
-
negate: !m[
|
108
|
+
tag: m["tag"].wildcard_to_rx,
|
109
|
+
comp: m["op"],
|
110
|
+
value: m["val"],
|
111
|
+
required: all_req || (!m["req"].nil? && m["req"] == "+"),
|
112
|
+
negate: !m["req"].nil? && m["req"] =~ /[!-]/ ? true : false,
|
110
113
|
})
|
111
114
|
end
|
112
115
|
|
@@ -127,9 +130,9 @@ class App
|
|
127
130
|
m = arg.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
|
128
131
|
|
129
132
|
tokens.push({
|
130
|
-
token: m[
|
131
|
-
required: all_req || (!m[
|
132
|
-
negate: !m[
|
133
|
+
token: m["tok"],
|
134
|
+
required: all_req || (!m["req"].nil? && m["req"] == "+"),
|
135
|
+
negate: !m["req"].nil? && m["req"] =~ /[!-]/ ? true : false,
|
133
136
|
})
|
134
137
|
end
|
135
138
|
end
|
@@ -140,9 +143,9 @@ class App
|
|
140
143
|
options[:in].split(/ *, */).each do |a|
|
141
144
|
m = a.match(/^(?<req>[+\-!])?(?<tok>.*?)$/)
|
142
145
|
todos.push({
|
143
|
-
token: m[
|
144
|
-
required: all_req || (!m[
|
145
|
-
negate: !m[
|
146
|
+
token: m["tok"],
|
147
|
+
required: all_req || (!m["req"].nil? && m["req"] == "+"),
|
148
|
+
negate: !m["req"].nil? && m["req"] =~ /[!-]/,
|
146
149
|
})
|
147
150
|
end
|
148
151
|
end
|
@@ -157,21 +160,22 @@ class App
|
|
157
160
|
negate: options[:invert],
|
158
161
|
regex: options[:regex],
|
159
162
|
project: options[:project],
|
160
|
-
require_na: false
|
163
|
+
require_na: false,
|
161
164
|
})
|
162
165
|
|
163
166
|
regexes = if tokens.is_a?(Array)
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
167
|
+
tokens.delete_if { |token| token[:negate] }.map { |token| token[:token].wildcard_to_rx }
|
168
|
+
else
|
169
|
+
[tokens]
|
170
|
+
end
|
168
171
|
|
169
172
|
todo.actions.output(depth,
|
170
|
-
files: todo.files,
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
173
|
+
{ files: todo.files,
|
174
|
+
regexes: regexes,
|
175
|
+
notes: options[:notes],
|
176
|
+
nest: options[:nest],
|
177
|
+
nest_projects: options[:omnifocus],
|
178
|
+
no_files: options[:no_file] })
|
175
179
|
end
|
176
180
|
end
|
177
181
|
end
|